diff --git a/.pnp.cjs b/.pnp.cjs index a7758f32aff..13460650039 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -4474,7 +4474,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/@types-bs58-npm-4.0.1-179273a650-5063fed6bb.zip/node_modules/@types/bs58/",\ "packageDependencies": [\ ["@types/bs58", "npm:4.0.1"],\ - ["base-x", "npm:3.0.9"]\ + ["base-x", "npm:3.0.11"]\ ],\ "linkType": "HARD"\ }]\ @@ -6517,10 +6517,10 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["base-x", [\ - ["npm:3.0.9", {\ - "packageLocation": "./.yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip/node_modules/base-x/",\ + ["npm:3.0.11", {\ + "packageLocation": "./.yarn/cache/base-x-npm-3.0.11-3798da0834-c2e3c443fd.zip/node_modules/base-x/",\ "packageDependencies": [\ - ["base-x", "npm:3.0.9"],\ + ["base-x", "npm:3.0.11"],\ ["safe-buffer", "npm:5.2.1"]\ ],\ "linkType": "HARD"\ @@ -6877,7 +6877,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/bs58-npm-4.0.1-8d2a7822b1-b3c5365bb9.zip/node_modules/bs58/",\ "packageDependencies": [\ ["bs58", "npm:4.0.1"],\ - ["base-x", "npm:3.0.9"]\ + ["base-x", "npm:3.0.11"]\ ],\ "linkType": "HARD"\ }]\ diff --git a/.yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip b/.yarn/cache/base-x-npm-3.0.11-3798da0834-c2e3c443fd.zip similarity index 50% rename from .yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip rename to .yarn/cache/base-x-npm-3.0.11-3798da0834-c2e3c443fd.zip index 79bdd2c7052..a47894a0b10 100644 Binary files a/.yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip and b/.yarn/cache/base-x-npm-3.0.11-3798da0834-c2e3c443fd.zip differ diff --git a/.yarn/cache/fsevents-patch-19706e7e35-10.zip b/.yarn/cache/fsevents-patch-19706e7e35-10.zip new file mode 100644 index 00000000000..aff1ab12ce5 Binary files /dev/null and b/.yarn/cache/fsevents-patch-19706e7e35-10.zip differ diff --git a/package.json b/package.json index 14b7d2a2968..6e5b826a89d 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,8 @@ "path-to-regexp": "^1.9.0", "cookie": "^0.7.0", "cross-spawn": "^7.0.5", - "nanoid": "^3.3.8" + "nanoid": "^3.3.8", + "base-x": "^3.0.11" }, "dependencies": { "node-gyp": "^10.0.1" diff --git a/packages/platform-test-suite/test/e2e/contacts.spec.js b/packages/platform-test-suite/test/e2e/contacts.spec.js index fe8eaf2fced..fceb6027730 100644 --- a/packages/platform-test-suite/test/e2e/contacts.spec.js +++ b/packages/platform-test-suite/test/e2e/contacts.spec.js @@ -104,9 +104,9 @@ describe('e2e', () => { describe('Bob', () => { it('should create user wallet and identity', async () => { // Create Bob wallet - bobClient = await createClientWithFundedWallet(500000); + bobClient = await createClientWithFundedWallet(150000000); // 1.5 Dash - bobIdentity = await bobClient.platform.identities.register(400000); + bobIdentity = await bobClient.platform.identities.register(140000000); // 1.4 Dash // Additional wait time to mitigate testnet latency await waitForSTPropagated(); diff --git a/packages/platform-test-suite/test/functional/platform/DataContract.spec.js b/packages/platform-test-suite/test/functional/platform/DataContract.spec.js index 28fe50b14ec..348740129b2 100644 --- a/packages/platform-test-suite/test/functional/platform/DataContract.spec.js +++ b/packages/platform-test-suite/test/functional/platform/DataContract.spec.js @@ -25,11 +25,11 @@ describe('Platform', () => { let identity; before(async () => { - client = await createClientWithFundedWallet(35000000); + client = await createClientWithFundedWallet(350000000); // 3.5 Dash // Looks like updating the contact and keeping history requires about // 7 million credits in fees. Investigate this further. - identity = await client.platform.identities.register(30000000); + identity = await client.platform.identities.register(300000000); // 3 Dash const nextNonce = await client.platform .nonceManager.bumpIdentityNonce(identity.getId()); dataContractFixture = await getDataContractFixture(nextNonce); diff --git a/packages/platform-test-suite/test/functional/platform/Document.spec.js b/packages/platform-test-suite/test/functional/platform/Document.spec.js index 85f9abf963a..f30c7b4feb4 100644 --- a/packages/platform-test-suite/test/functional/platform/Document.spec.js +++ b/packages/platform-test-suite/test/functional/platform/Document.spec.js @@ -38,9 +38,9 @@ describe('Platform', () => { let document; before(async () => { - client = await createClientWithFundedWallet(1010000); + client = await createClientWithFundedWallet(101000000); // 1 Dash - identity = await client.platform.identities.register(1000000); + identity = await client.platform.identities.register(100000000); // Additional wait time to mitigate testnet latency await waitForSTPropagated(); diff --git a/packages/platform-test-suite/test/functional/platform/Identity.spec.js b/packages/platform-test-suite/test/functional/platform/Identity.spec.js index 8f5e8994c40..8238ff38a37 100644 --- a/packages/platform-test-suite/test/functional/platform/Identity.spec.js +++ b/packages/platform-test-suite/test/functional/platform/Identity.spec.js @@ -38,7 +38,7 @@ describe('Platform', () => { let walletAccount; before(async () => { - client = await createClientWithFundedWallet(20000000); + client = await createClientWithFundedWallet(150000000); // 1.5 Dash walletAccount = await client.getWalletAccount(); }); @@ -50,7 +50,7 @@ describe('Platform', () => { }); it('should create an identity', async () => { - identity = await client.platform.identities.register(400000); + identity = await client.platform.identities.register(140000000); // 1.4 Dash expect(identity).to.exist(); }); diff --git a/packages/rs-dpp/src/data_contract/document_type/class_methods/mod.rs b/packages/rs-dpp/src/data_contract/document_type/class_methods/mod.rs index 77a2dca60c6..bfad96e4a76 100644 --- a/packages/rs-dpp/src/data_contract/document_type/class_methods/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/class_methods/mod.rs @@ -9,7 +9,7 @@ mod create_document_types_from_document_schemas; mod try_from_schema; #[inline] -fn consensus_or_protocol_data_contract_error( +pub(crate) fn consensus_or_protocol_data_contract_error( data_contract_error: DataContractError, ) -> ProtocolError { #[cfg(feature = "validation")] @@ -25,7 +25,9 @@ fn consensus_or_protocol_data_contract_error( } #[inline] -fn consensus_or_protocol_value_error(platform_value_error: platform_value::Error) -> ProtocolError { +pub(crate) fn consensus_or_protocol_value_error( + platform_value_error: platform_value::Error, +) -> ProtocolError { #[cfg(feature = "validation")] { ProtocolError::ConsensusError( diff --git a/packages/rs-dpp/src/data_contract/document_type/mod.rs b/packages/rs-dpp/src/data_contract/document_type/mod.rs index b7b22fdff63..165afc0e254 100644 --- a/packages/rs-dpp/src/data_contract/document_type/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/mod.rs @@ -38,7 +38,7 @@ pub const EMPTY_TREE_STORAGE_SIZE: usize = 33; pub const MAX_INDEX_SIZE: usize = 255; pub const STORAGE_FLAGS_SIZE: usize = 2; -mod property_names { +pub(crate) mod property_names { pub const DOCUMENTS_KEEP_HISTORY: &str = "documentsKeepHistory"; pub const DOCUMENTS_MUTABLE: &str = "documentsMutable"; diff --git a/packages/rs-dpp/src/data_contract/methods/mod.rs b/packages/rs-dpp/src/data_contract/methods/mod.rs index 279eafce441..04f79db8876 100644 --- a/packages/rs-dpp/src/data_contract/methods/mod.rs +++ b/packages/rs-dpp/src/data_contract/methods/mod.rs @@ -1,4 +1,5 @@ mod equal_ignoring_time_based_fields; +mod registration_cost; pub mod schema; #[cfg(feature = "validation")] pub mod validate_document; diff --git a/packages/rs-dpp/src/data_contract/methods/registration_cost/mod.rs b/packages/rs-dpp/src/data_contract/methods/registration_cost/mod.rs new file mode 100644 index 00000000000..aed872ccf12 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/methods/registration_cost/mod.rs @@ -0,0 +1,84 @@ +mod v1; + +use crate::data_contract::serialized_version::DataContractInSerializationFormat; +use crate::data_contract::DataContract; +use crate::ProtocolError; +use platform_version::version::PlatformVersion; + +impl DataContract { + /// Returns the registration cost of the data contract based on the current platform version + /// and the number of associated search keywords. + /// + /// This method dispatches to a version-specific implementation based on the + /// platform version configuration. If the version is unrecognized, it returns a version mismatch error. + /// + /// # Arguments + /// - `platform_version`: A reference to the platform version, used to determine which + /// registration cost algorithm to apply. + /// + /// # Returns + /// - `Ok(u64)`: The total registration cost in credits for this contract. + /// - `Err(ProtocolError)`: If the platform version is unrecognized or if the fee computation overflows. + /// + /// # Version Behavior + /// - Version 0: Always returns `0` (used before protocol version 9, ie before 2.0, where registration cost was not charged). + /// - Version 1: Uses a detailed cost model based on document types, indexes, tokens, and keyword count. + pub fn registration_cost( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .dpp + .contract_versions + .methods + .registration_cost + { + 0 => Ok(0), // Before 2.0 it's just 0 (There was some validation cost) + 1 => Ok(self.registration_cost_v1(platform_version)), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::registration_cost".to_string(), + known_versions: vec![0, 1], + received: version, + }), + } + } +} + +impl DataContractInSerializationFormat { + /// Returns the registration cost of the data contract based on the current platform version + /// and the number of associated search keywords. + /// + /// This method dispatches to a version-specific implementation based on the + /// platform version configuration. If the version is unrecognized, it returns a version mismatch error. + /// + /// # Arguments + /// - `platform_version`: A reference to the platform version, used to determine which + /// registration cost algorithm to apply. + /// + /// # Returns + /// - `Ok(u64)`: The total registration cost in credits for this contract. + /// - `Err(ProtocolError)`: If the platform version is unrecognized or if the fee computation overflows. + /// + /// # Version Behavior + /// - Version 0: Always returns `0` (used before protocol version 9, ie before 2.0, where registration cost was not charged). + /// - Version 1: Uses a detailed cost model based on document types, indexes, tokens, and keyword count. + pub fn registration_cost( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .dpp + .contract_versions + .methods + .registration_cost + { + 0 => Ok(0), // Before 2.0 it's just 0 (There was some validation cost) + 1 => Ok(self.registration_cost_v1(platform_version)), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::registration_cost".to_string(), + known_versions: vec![0, 1], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/data_contract/methods/registration_cost/v1/mod.rs b/packages/rs-dpp/src/data_contract/methods/registration_cost/v1/mod.rs new file mode 100644 index 00000000000..6dce1253630 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/methods/registration_cost/v1/mod.rs @@ -0,0 +1,159 @@ +use crate::data_contract::accessors::v0::DataContractV0Getters; +use crate::data_contract::accessors::v1::DataContractV1Getters; +use crate::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; +use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; +use crate::data_contract::document_type::Index; +use crate::data_contract::serialized_version::DataContractInSerializationFormat; +use crate::fee::Credits; +use crate::prelude::DataContract; +use platform_value::Value; +use platform_version::version::PlatformVersion; + +impl DataContract { + /// Computes the registration cost of a data contract based on its document types, + /// indexes, token configurations, and keyword count. + /// + /// # Parameters + /// - `platform_version`: A reference to the current platform version providing fee parameters. + /// + /// # Returns + /// - `Ok(Credits)`: The total registration cost in credits if all additions are overflow-safe. + /// - `Err(ProtocolError)`: If any arithmetic operation results in overflow. + /// + /// # Fee Components + /// - Base contract registration fee. + /// - Per document type registration fee. + /// - Per index registration fee (unique and non-unique). + /// - Token registration fee per token. + /// - Additional fees for tokens using perpetual or pre-programmed distribution. + /// - Search keyword fees (`keyword_count * search_keyword_fee`). + pub(super) fn registration_cost_v1(&self, platform_version: &PlatformVersion) -> Credits { + let fee_version = &platform_version.fee_version.data_contract_registration; + let mut cost = fee_version.base_contract_registration_fee; + + for document_type in self.document_types().values() { + cost = cost.saturating_add(fee_version.document_type_registration_fee); + + for index in document_type.indexes().values() { + let base_index_fee = if index.contested_index.is_some() { + fee_version.document_type_base_contested_index_registration_fee + } else if index.unique { + fee_version.document_type_base_unique_index_registration_fee + } else { + fee_version.document_type_base_non_unique_index_registration_fee + }; + + cost = cost.saturating_add(base_index_fee); + } + } + + for token_config in self.tokens().values() { + cost = cost.saturating_add(fee_version.token_registration_fee); + + if token_config + .distribution_rules() + .perpetual_distribution() + .is_some() + { + cost = cost.saturating_add(fee_version.token_uses_perpetual_distribution_fee); + } + + if token_config + .distribution_rules() + .pre_programmed_distribution() + .is_some() + { + cost = cost.saturating_add(fee_version.token_uses_pre_programmed_distribution_fee); + } + } + + let keyword_cost = fee_version + .search_keyword_fee + .saturating_mul(self.keywords().len() as u64); + + cost = cost.saturating_add(keyword_cost); + + cost + } +} + +impl DataContractInSerializationFormat { + /// Computes the registration cost of a data contract based on its document types, + /// indexes, token configurations, and keyword count. + /// + /// # Parameters + /// - `platform_version`: A reference to the current platform version providing fee parameters. + /// + /// # Returns + /// - `Ok(Credits)`: The total registration cost in credits if all additions are overflow-safe. + /// - `Err(ProtocolError)`: If any arithmetic operation results in overflow. + /// + /// # Fee Components + /// - Base contract registration fee. + /// - Per document type registration fee. + /// - Per index registration fee (unique and non-unique). + /// - Token registration fee per token. + /// - Additional fees for tokens using perpetual or pre-programmed distribution. + /// - Search keyword fees (`keyword_count * search_keyword_fee`). + pub(super) fn registration_cost_v1(&self, platform_version: &PlatformVersion) -> Credits { + let fee_version = &platform_version.fee_version.data_contract_registration; + let mut cost = fee_version.base_contract_registration_fee; + + for document_type_schema in self.document_schemas().values() { + cost = cost.saturating_add(fee_version.document_type_registration_fee); + + // If this is not okay the registration will fail on basic validation + if let Ok(schema_map) = document_type_schema.to_map() { + // Initialize indices + if let Ok(Some(index_values)) = Value::inner_optional_array_slice_value( + schema_map, + crate::data_contract::document_type::property_names::INDICES, + ) { + for index_value in index_values { + if let Ok(index_value_map) = index_value.to_map() { + if let Ok(index) = Index::try_from(index_value_map.as_slice()) { + let base_index_fee = if index.contested_index.is_some() { + fee_version.document_type_base_contested_index_registration_fee + } else if index.unique { + fee_version.document_type_base_unique_index_registration_fee + } else { + fee_version.document_type_base_non_unique_index_registration_fee + }; + cost = cost.saturating_add(base_index_fee); + } + } + } + } + }; + } + + for token_config in self.tokens().values() { + cost = cost.saturating_add(fee_version.token_registration_fee); + + if token_config + .distribution_rules() + .perpetual_distribution() + .is_some() + { + cost = cost.saturating_add(fee_version.token_uses_perpetual_distribution_fee); + } + + if token_config + .distribution_rules() + .pre_programmed_distribution() + .is_some() + { + cost = cost.saturating_add(fee_version.token_uses_pre_programmed_distribution_fee); + } + } + + let keyword_cost = fee_version + .search_keyword_fee + .saturating_mul(self.keywords().len() as u64); + + cost = cost.saturating_add(keyword_cost); + + cost + } +} diff --git a/packages/rs-dpp/src/fee/fee_result/mod.rs b/packages/rs-dpp/src/fee/fee_result/mod.rs index f0fbbc41a2b..b87c9f77856 100644 --- a/packages/rs-dpp/src/fee/fee_result/mod.rs +++ b/packages/rs-dpp/src/fee/fee_result/mod.rs @@ -210,7 +210,7 @@ impl FeeResult { /// Convenience method to get total fee pub fn total_base_fee(&self) -> Credits { - self.storage_fee + self.processing_fee + self.storage_fee.saturating_add(self.processing_fee) } /// Convenience method to get required removed balance diff --git a/packages/rs-dpp/src/validation/operations.rs b/packages/rs-dpp/src/validation/operations.rs index 477f1eb06a1..abcf1140255 100644 --- a/packages/rs-dpp/src/validation/operations.rs +++ b/packages/rs-dpp/src/validation/operations.rs @@ -14,19 +14,19 @@ impl ProtocolValidationOperation { ProtocolValidationOperation::DocumentTypeSchemaValidationForSize(size) => { platform_version .fee_version - .data_contract + .data_contract_validation .document_type_base_fee + *size * platform_version .fee_version - .data_contract - .document_type_size_fee + .data_contract_validation + .document_type_schema_size_fee } ProtocolValidationOperation::DocumentTypeSchemaPropertyValidation(properties_count) => { *properties_count * platform_version .fee_version - .data_contract + .data_contract_validation .document_type_per_property_fee } ProtocolValidationOperation::DocumentTypeSchemaIndexValidation( @@ -37,21 +37,21 @@ impl ProtocolValidationOperation { *index_properties_count * platform_version .fee_version - .data_contract + .data_contract_validation .document_type_unique_index_per_property_fee + platform_version .fee_version - .data_contract + .data_contract_validation .document_type_base_unique_index_fee } else { *index_properties_count * platform_version .fee_version - .data_contract + .data_contract_validation .document_type_non_unique_index_per_property_fee + platform_version .fee_version - .data_contract + .data_contract_validation .document_type_base_non_unique_index_fee } } diff --git a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs index 3e794714efd..94caa353ba5 100644 --- a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs @@ -459,7 +459,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -559,7 +559,7 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 1000000000, + balance: 25_000_000_000, // 0.25 Dash revision: 0, } .into(); @@ -602,7 +602,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -630,7 +630,10 @@ mod tests { ) .expect("expected to process state transition"); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2489210); + assert_eq!( + processing_result.aggregated_fees().processing_fee, + 24002489210 + ); let check_result = platform .check_tx( @@ -709,7 +712,7 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 1000000000, + balance: 27_000_000_000, revision: 0, } .into(); @@ -803,7 +806,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -953,7 +956,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); assert_eq!(validation_result.data.unwrap().priority, 10000); @@ -1068,7 +1071,7 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 1000000000, + balance: 25_000_000_000, // 0.25 Dash revision: 0, } .into(); @@ -1107,7 +1110,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); assert_eq!(validation_result.data.unwrap().priority, 10000); @@ -1141,7 +1144,11 @@ mod tests { // The processing fees should be twice as much as a fee multiplier of 0, // since a fee multiplier of 100 means 100% more of 1 (gives 2) - assert_eq!(processing_result.aggregated_fees().processing_fee, 4978420); + // Plus we have 24_000_000_000 in base costs + assert_eq!( + processing_result.aggregated_fees().processing_fee, + 24004978420 + ); let check_result = platform .check_tx( @@ -1222,7 +1229,7 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 200000000, // we have enough balance only for 1 insertion (this is where this test is different) + balance: 24_200_000_000, // we have enough balance only for 1 insertion (this is where this test is different) revision: 0, } .into(); @@ -1258,7 +1265,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -1456,7 +1463,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -1569,7 +1576,7 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 1000000000, + balance: 100_000_000_000, // 1.0 Dash revision: 0, } .into(); @@ -1613,7 +1620,10 @@ mod tests { ) .expect("expected to process state transition"); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2489210); + assert_eq!( + processing_result.aggregated_fees().processing_fee, + 24002489210 + ); platform .drive @@ -1666,7 +1676,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -1699,7 +1709,7 @@ mod tests { assert_eq!( update_processing_result.aggregated_fees().processing_fee, - 2504030 + 27002504030 ); let check_result = platform @@ -1915,7 +1925,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -2025,7 +2035,7 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 1000000000, + balance: 100_000_000_000, // 1 Dash revision: 0, } .into(); @@ -2069,7 +2079,10 @@ mod tests { ) .expect("expected to process state transition"); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2489210); + assert_eq!( + processing_result.aggregated_fees().processing_fee, + 24002489210 + ); platform .drive @@ -2160,7 +2173,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let check_result = platform .check_tx( @@ -2425,7 +2438,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); } #[test] @@ -2560,7 +2573,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let transaction = platform.drive.grove.start_transaction(); @@ -2709,7 +2722,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let transaction = platform.drive.grove.start_transaction(); @@ -2994,7 +3007,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let transaction = platform.drive.grove.start_transaction(); @@ -3296,7 +3309,7 @@ mod tests { ) .expect("expected to check tx"); - assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.errors.as_slice(), &[]); let transaction = platform.drive.grove.start_transaction(); diff --git a/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/execute_event/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/execute_event/v0/mod.rs index 87004687898..61c4342481a 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/execute_event/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/execute_event/v0/mod.rs @@ -13,14 +13,86 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::fee::fee_result::FeeResult; +use dpp::fee::Credits; +use dpp::identity::PartialIdentity; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use dpp::version::PlatformVersion; use drive::drive::identity::update::apply_balance_change_outcome::ApplyBalanceChangeOutcomeV0Methods; use drive::grovedb::Transaction; +use drive::util::batch::DriveOperation; impl Platform where C: CoreRPCLike, { + #[allow(clippy::too_many_arguments)] + fn paid_function( + &self, + mut fee_validation_result: ConsensusValidationResult, + identity: PartialIdentity, + operations: Vec, + execution_operations: Vec, + user_fee_increase: UserFeeIncrease, + additional_fixed_fee_cost: Option, + block_info: &BlockInfo, + mut consensus_errors: Vec, + transaction: &Transaction, + platform_version: &PlatformVersion, + previous_fee_versions: &CachedEpochIndexFeeVersions, + ) -> Result { + if fee_validation_result.is_valid_with_data() { + //todo: make this into an atomic event with partial batches + let mut individual_fee_result = self + .drive + .apply_drive_operations( + operations, + true, + block_info, + Some(transaction), + platform_version, + Some(previous_fee_versions), + ) + .map_err(Error::Drive)?; + + ValidationOperation::add_many_to_fee_result( + &execution_operations, + &mut individual_fee_result, + platform_version, + )?; + + individual_fee_result.apply_user_fee_increase(user_fee_increase); + + if let Some(additional_fixed_fee_cost) = additional_fixed_fee_cost { + individual_fee_result.processing_fee = individual_fee_result + .processing_fee + .saturating_add(additional_fixed_fee_cost); + } + + let balance_change = individual_fee_result.into_balance_change(identity.id); + + let outcome = self.drive.apply_balance_change_from_fee_to_identity( + balance_change, + Some(transaction), + platform_version, + )?; + + if consensus_errors.is_empty() { + Ok(SuccessfulPaidExecution( + Some(fee_validation_result.into_data()?), + outcome.actual_fee_paid_owned(), + )) + } else { + Ok(UnsuccessfulPaidExecution( + Some(fee_validation_result.into_data()?), + outcome.actual_fee_paid_owned(), + consensus_errors, + )) + } + } else { + consensus_errors.append(&mut fee_validation_result.errors); + Ok(UnpaidConsensusExecutionError(consensus_errors)) + } + } /// Executes the given `event` based on the `block_info` and `transaction`. /// /// This function takes an `ExecutionEvent`, `BlockInfo`, and `Transaction` as input and performs @@ -47,7 +119,7 @@ where pub(super) fn execute_event_v0( &self, event: ExecutionEvent, - mut consensus_errors: Vec, + consensus_errors: Vec, block_info: &BlockInfo, transaction: &Transaction, platform_version: &PlatformVersion, @@ -75,62 +147,46 @@ where execution_operations, user_fee_increase, .. + } => { + // We can unwrap here because we have the match right above + let fee_validation_result = maybe_fee_validation_result.unwrap(); + self.paid_function( + fee_validation_result, + identity, + operations, + execution_operations, + user_fee_increase, + None, + block_info, + consensus_errors, + transaction, + platform_version, + previous_fee_versions, + ) } - | ExecutionEvent::Paid { + ExecutionEvent::Paid { identity, operations, execution_operations, + additional_fixed_fee_cost, user_fee_increase, .. } => { // We can unwrap here because we have the match right above - let mut fee_validation_result = maybe_fee_validation_result.unwrap(); - if fee_validation_result.is_valid_with_data() { - //todo: make this into an atomic event with partial batches - let mut individual_fee_result = self - .drive - .apply_drive_operations( - operations, - true, - block_info, - Some(transaction), - platform_version, - Some(previous_fee_versions), - ) - .map_err(Error::Drive)?; - - ValidationOperation::add_many_to_fee_result( - &execution_operations, - &mut individual_fee_result, - platform_version, - )?; - - individual_fee_result.apply_user_fee_increase(user_fee_increase); - - let balance_change = individual_fee_result.into_balance_change(identity.id); - - let outcome = self.drive.apply_balance_change_from_fee_to_identity( - balance_change, - Some(transaction), - platform_version, - )?; - - if consensus_errors.is_empty() { - Ok(SuccessfulPaidExecution( - Some(fee_validation_result.into_data()?), - outcome.actual_fee_paid_owned(), - )) - } else { - Ok(UnsuccessfulPaidExecution( - Some(fee_validation_result.into_data()?), - outcome.actual_fee_paid_owned(), - consensus_errors, - )) - } - } else { - consensus_errors.append(&mut fee_validation_result.errors); - Ok(UnpaidConsensusExecutionError(consensus_errors)) - } + let fee_validation_result = maybe_fee_validation_result.unwrap(); + self.paid_function( + fee_validation_result, + identity, + operations, + execution_operations, + user_fee_increase, + additional_fixed_fee_cost, + block_info, + consensus_errors, + transaction, + platform_version, + previous_fee_versions, + ) } // This is for Partially used Asset Locks // NOT used for identity create or identity top up diff --git a/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/validate_fees_of_event/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/validate_fees_of_event/v0/mod.rs index 04e8f0f503e..b8810cec48a 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/validate_fees_of_event/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/state_transition_processing/validate_fees_of_event/v0/mod.rs @@ -101,6 +101,7 @@ where removed_balance, operations, execution_operations, + additional_fixed_fee_cost: additional_fee_cost, user_fee_increase, } => { let balance = identity.balance.ok_or(Error::Execution( @@ -131,7 +132,12 @@ where estimated_fee_result.apply_user_fee_increase(*user_fee_increase); // TODO: Should take into account refunds as well - let required_balance = estimated_fee_result.total_base_fee(); + let mut required_balance = estimated_fee_result.total_base_fee(); + + if let Some(additional_fee_cost) = additional_fee_cost { + required_balance += *additional_fee_cost; + } + if balance_after_principal_operation >= required_balance { Ok(ConsensusValidationResult::new_with_data( estimated_fee_result, diff --git a/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs b/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs index a0eb4605360..8c85e10f796 100644 --- a/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs +++ b/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs @@ -33,6 +33,8 @@ pub(in crate::execution) enum ExecutionEvent<'a> { operations: Vec>, /// the execution operations that we must also pay for execution_operations: Vec, + /// Additional fee cost, these are processing fees where the user fee increase does not apply + additional_fixed_fee_cost: Option, /// the fee multiplier that the user agreed to, 0 means 100% of the base fee, 1 means 101% user_fee_increase: UserFeeIncrease, }, @@ -135,6 +137,7 @@ impl ExecutionEvent<'_> { removed_balance: Some(removed_balance), operations, execution_operations: execution_context.operations_consume(), + additional_fixed_fee_cost: None, user_fee_increase, }) } else { @@ -154,6 +157,7 @@ impl ExecutionEvent<'_> { removed_balance: Some(removed_balance), operations, execution_operations: execution_context.operations_consume(), + additional_fixed_fee_cost: None, user_fee_increase, }) } else { @@ -173,6 +177,7 @@ impl ExecutionEvent<'_> { removed_balance, operations, execution_operations: execution_context.operations_consume(), + additional_fixed_fee_cost: None, user_fee_increase, }) } else { @@ -193,6 +198,52 @@ impl ExecutionEvent<'_> { .contested_document_single_vote_cost, }) } + StateTransitionAction::DataContractCreateAction(data_contract_create_action) => { + let user_fee_increase = action.user_fee_increase(); + let registration_cost = data_contract_create_action + .data_contract_ref() + .registration_cost(platform_version)?; + let operations = + action.into_high_level_drive_operations(epoch, platform_version)?; + if let Some(identity) = identity { + Ok(ExecutionEvent::Paid { + identity, + removed_balance: None, + operations, + execution_operations: execution_context.operations_consume(), + additional_fixed_fee_cost: Some(registration_cost), + user_fee_increase, + }) + } else { + Err(Error::Execution(ExecutionError::CorruptedCodeExecution( + "partial identity should be present for other state transitions", + ))) + } + } + StateTransitionAction::DataContractUpdateAction(data_contract_update_action) => { + let user_fee_increase = action.user_fee_increase(); + // The update cost pays for the whole contract again, that's fine for now. + // It would be a lot of work to fix this, so we'll just go with this for now. + let registration_cost = data_contract_update_action + .data_contract_ref() + .registration_cost(platform_version)?; + let operations = + action.into_high_level_drive_operations(epoch, platform_version)?; + if let Some(identity) = identity { + Ok(ExecutionEvent::Paid { + identity, + removed_balance: None, + operations, + execution_operations: execution_context.operations_consume(), + additional_fixed_fee_cost: Some(registration_cost), + user_fee_increase, + }) + } else { + Err(Error::Execution(ExecutionError::CorruptedCodeExecution( + "partial identity should be present for other state transitions", + ))) + } + } _ => { let user_fee_increase = action.user_fee_increase(); let operations = @@ -203,6 +254,7 @@ impl ExecutionEvent<'_> { removed_balance: None, operations, execution_operations: execution_context.operations_consume(), + additional_fixed_fee_cost: None, user_fee_increase, }) } else { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs index 9a9e2f8901f..59599801284 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs @@ -2,6 +2,8 @@ use crate::error::execution::ExecutionError; use crate::error::Error; use dpp::consensus::state::identity::IdentityInsufficientBalanceError; use dpp::identity::PartialIdentity; +use dpp::state_transition::data_contract_create_transition::accessors::DataContractCreateTransitionAccessorsV0; +use dpp::state_transition::data_contract_update_transition::accessors::DataContractUpdateTransitionAccessorsV0; use dpp::state_transition::StateTransition; use dpp::validation::SimpleConsensusValidationResult; use dpp::version::PlatformVersion; @@ -21,17 +23,27 @@ impl ValidateSimplePreCheckBalanceV0 for StateTransition { platform_version: &PlatformVersion, ) -> Result { let amount = match self { - StateTransition::DataContractCreate(_) => { + StateTransition::DataContractCreate(data_contract_create_transition) => { platform_version .fee_version .state_transition_min_fees .contract_create + .saturating_add( + data_contract_create_transition + .data_contract() + .registration_cost(platform_version)?, + ) } - StateTransition::DataContractUpdate(_) => { + StateTransition::DataContractUpdate(data_contract_update_transition) => { platform_version .fee_version .state_transition_min_fees .contract_update + .saturating_add( + data_contract_update_transition + .data_contract() + .registration_cost(platform_version)?, + ) } StateTransition::Batch(_) => { platform_version diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs index 9810a027ae2..a3b98f6e8a4 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs @@ -223,6 +223,70 @@ mod tests { let platform_state = platform.state.load(); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(2.0)); + + let data_contract = json_document_to_contract_with_ids( + "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index.json", + None, + None, + false, //no need to validate the data contracts in tests for drive + platform_version, + ) + .expect("expected to get json based contract"); + + let data_contract_create_transition = DataContractCreateTransition::new_from_data_contract( + data_contract, + 1, + &identity.into_partial_identity_info(), + key.id(), + &signer, + platform_version, + None, + ) + .expect("expect to create documents batch transition"); + + let data_contract_create_serialized_transition = data_contract_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &[data_contract_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + } + + #[test] + fn test_data_contract_creation_with_contested_unique_index_old_version_has_low_fees() { + let platform_version = PlatformVersion::get(8).unwrap(); + let mut platform = TestPlatformBuilder::new() + .with_initial_protocol_version(8) + .build_with_mock_rpc() + .set_genesis_state(); + + let platform_state = platform.state.load(); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); let data_contract = json_document_to_contract_with_ids( @@ -286,7 +350,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(2.0)); let data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-with-contract-id.json", @@ -349,7 +413,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(2.0)); let data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-and-other-unique-index.json", @@ -428,7 +492,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -521,7 +585,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 234, dash_to_credits!(0.1)); @@ -649,7 +713,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -743,7 +807,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, contract_signer, contract_key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/crypto-card-game/crypto-card-game-in-game-currency.json", @@ -848,7 +912,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, contract_signer, contract_key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/crypto-card-game/crypto-card-game-in-game-currency.json", @@ -954,7 +1018,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _signer_2, _key_2) = setup_identity(&mut platform, 93, dash_to_credits!(0.5)); @@ -1060,7 +1124,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, contract_signer, contract_key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (token_contract_owner_id, _, _) = setup_identity(&mut platform, 11, dash_to_credits!(0.1)); @@ -1183,7 +1247,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -1303,7 +1367,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 5456, dash_to_credits!(0.1)); @@ -1487,7 +1551,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -1581,7 +1645,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 564, dash_to_credits!(0.1)); @@ -1694,7 +1758,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 564, dash_to_credits!(0.1)); @@ -1808,7 +1872,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -1916,7 +1980,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -2015,7 +2079,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -2150,7 +2214,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, contract_signer, contract_key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (token_contract_owner_id, _, _) = setup_identity(&mut platform, 11, dash_to_credits!(0.1)); @@ -2277,7 +2341,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -2395,7 +2459,7 @@ mod tests { let platform_state = platform.state.load(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -2503,7 +2567,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 234, dash_to_credits!(0.1)); @@ -2634,7 +2698,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 234, dash_to_credits!(0.1)); @@ -2762,7 +2826,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 234, dash_to_credits!(0.1)); @@ -2891,7 +2955,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 234, dash_to_credits!(0.1)); @@ -3019,7 +3083,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 234, dash_to_credits!(0.1)); @@ -3147,7 +3211,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 234, dash_to_credits!(0.1)); @@ -3291,7 +3355,7 @@ mod tests { let platform_state = platform.state.load(); // Create a test identity and keys - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // Load the base contract JSON and convert it to `DataContract` let data_contract = json_document_to_contract_with_ids( @@ -3373,7 +3437,7 @@ mod tests { let platform_state = platform.state.load(); // Create a test identity and keys - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // Load the base contract JSON and convert it to `DataContract` let data_contract = json_document_to_contract_with_ids( @@ -3457,7 +3521,7 @@ mod tests { let platform_state = platform.state.load(); // Create identity - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // Load the base contract JSON and convert it to `DataContract` let data_contract = json_document_to_contract_with_ids( @@ -3531,7 +3595,7 @@ mod tests { .set_genesis_state(); let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let data_contract = json_document_to_contract_with_ids( "tests/supporting_files/contract/keyword_test/keyword_base_contract.json", @@ -3602,7 +3666,7 @@ mod tests { let platform_state = platform.state.load(); // Create a test identity and keys - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // Load the base contract JSON and convert to `DataContract` let data_contract = json_document_to_contract_with_ids( @@ -3801,7 +3865,7 @@ mod tests { .set_genesis_state(); let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // --- mutate the contract --- let mut contract_value = base_contract_value_with_keyword(platform_version); @@ -3856,7 +3920,7 @@ mod tests { .set_genesis_state(); let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut contract_value = base_contract_value_with_keyword(platform_version); // 101 chars – valid for the contract (max 10 000) but exceeds the @@ -3913,7 +3977,7 @@ mod tests { .set_genesis_state(); let platform_state = platform.state.load(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let mut contract_value = base_contract_value_with_keyword(platform_version); contract_value["description"] = diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs index 5f6663790c8..88d48caa5c8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs @@ -610,7 +610,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let card_game_path = "tests/supporting_files/contract/crypto-card-game/crypto-card-game-direct-purchase-creation-restricted-to-owner.json"; @@ -714,7 +714,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = platform_state @@ -837,7 +837,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = platform_state @@ -966,7 +966,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = platform_state @@ -1080,7 +1080,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity_2, _, _) = setup_identity(&mut platform, 928, dash_to_credits!(0.1)); @@ -1234,7 +1234,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = platform_state @@ -1336,7 +1336,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let (identity2, _signer2, _key2) = setup_identity(&mut platform, 93, dash_to_credits!(0.2)); @@ -1436,7 +1436,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = PlatformVersion::latest(); @@ -1542,7 +1542,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = platform_state @@ -1647,7 +1647,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = platform_state @@ -1734,7 +1734,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = platform_state @@ -2108,7 +2108,7 @@ mod tests { .build_with_mock_rpc() .set_initial_state_structure(); let (identity, signer, key) = - setup_identity(&mut platform, 1234, dash_to_credits!(0.1)); + setup_identity(&mut platform, 1234, dash_to_credits!(1.0)); let platform_state = platform.state.load(); let platform_version = PlatformVersion::latest(); @@ -2452,7 +2452,7 @@ mod tests { .set_genesis_state(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(10.0)); // create initial contract with one keyword so update is allowed let (cid, _) = create_contract_with_keywords( @@ -2529,7 +2529,7 @@ mod tests { .build_with_mock_rpc() .set_genesis_state(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // initial contract with two keywords let (cid, _) = create_contract_with_keywords( @@ -2832,7 +2832,7 @@ mod tests { .set_genesis_state(); let (identity, signer, key) = - setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // create initial contract with description so update is allowed let (cid, _) = create_contract_with_description( @@ -2894,7 +2894,7 @@ mod tests { .build_with_mock_rpc() .set_genesis_state(); - let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(1.0)); // initial contract with description let (cid, _) = create_contract_with_description( diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs index fae14c1ed5c..80a573de920 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs @@ -25,6 +25,7 @@ pub struct DataContractMethodVersions { pub schema: FeatureVersion, pub validate_groups: FeatureVersion, pub equal_ignoring_time_fields: FeatureVersion, + pub registration_cost: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v1.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v1.rs index c7060f812e7..4cbe0a93817 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v1.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v1.rs @@ -21,6 +21,7 @@ pub const CONTRACT_VERSIONS_V1: DPPContractVersions = DPPContractVersions { schema: 0, validate_groups: 0, equal_ignoring_time_fields: 0, + registration_cost: 0, }, document_type_versions: DocumentTypeVersions { index_versions: DocumentTypeIndexVersions { diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs index ff8fa7c824f..3c11b5b5fc9 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs @@ -21,6 +21,7 @@ pub const CONTRACT_VERSIONS_V2: DPPContractVersions = DPPContractVersions { schema: 0, validate_groups: 0, equal_ignoring_time_fields: 0, + registration_cost: 1, //changed to version 1 }, document_type_versions: DocumentTypeVersions { index_versions: DocumentTypeIndexVersions { diff --git a/packages/rs-platform-version/src/version/fee/data_contract/mod.rs b/packages/rs-platform-version/src/version/fee/data_contract/mod.rs deleted file mode 100644 index 96921030e1c..00000000000 --- a/packages/rs-platform-version/src/version/fee/data_contract/mod.rs +++ /dev/null @@ -1,46 +0,0 @@ -use bincode::{Decode, Encode}; - -pub mod v1; - -#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)] -pub struct FeeDataContractValidationVersion { - pub document_type_base_fee: u64, - pub document_type_size_fee: u64, - pub document_type_per_property_fee: u64, - pub document_type_base_non_unique_index_fee: u64, - pub document_type_non_unique_index_per_property_fee: u64, - pub document_type_base_unique_index_fee: u64, - pub document_type_unique_index_per_property_fee: u64, -} - -#[cfg(test)] -mod tests { - use super::FeeDataContractValidationVersion; - - #[test] - // If this test failed, then a new field was added in FeeDataContractValidationVersion. And the corresponding eq needs to be updated as well - fn test_fee_data_contract_validation_fees_version_equality() { - let version1 = FeeDataContractValidationVersion { - document_type_base_fee: 1, - document_type_size_fee: 2, - document_type_per_property_fee: 3, - document_type_base_non_unique_index_fee: 4, - document_type_non_unique_index_per_property_fee: 5, - document_type_base_unique_index_fee: 6, - document_type_unique_index_per_property_fee: 7, - }; - - let version2 = FeeDataContractValidationVersion { - document_type_base_fee: 1, - document_type_size_fee: 2, - document_type_per_property_fee: 3, - document_type_base_non_unique_index_fee: 4, - document_type_non_unique_index_per_property_fee: 5, - document_type_base_unique_index_fee: 6, - document_type_unique_index_per_property_fee: 7, - }; - - // This assertion will check if all fields are considered in the equality comparison - assert_eq!(version1, version2, "FeeDataContractValidationVersion equality test failed. If a field was added or removed, update the Eq implementation."); - } -} diff --git a/packages/rs-platform-version/src/version/fee/data_contract_registration/mod.rs b/packages/rs-platform-version/src/version/fee/data_contract_registration/mod.rs new file mode 100644 index 00000000000..aa3eeb7940f --- /dev/null +++ b/packages/rs-platform-version/src/version/fee/data_contract_registration/mod.rs @@ -0,0 +1,21 @@ +use bincode::{Decode, Encode}; + +pub mod v1; +pub mod v2; + +/// These are the fee costs for various actions excluding validation +/// Re-Validation will happen on data contract update which is why we don't bundle them +/// together. +#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)] +pub struct FeeDataContractRegistrationVersion { + pub base_contract_registration_fee: u64, + pub document_type_registration_fee: u64, + pub document_type_base_non_unique_index_registration_fee: u64, + pub document_type_base_unique_index_registration_fee: u64, + /// All contested indexes are unique, but if the index is contested you only apply this fee + pub document_type_base_contested_index_registration_fee: u64, + pub token_registration_fee: u64, + pub token_uses_perpetual_distribution_fee: u64, + pub token_uses_pre_programmed_distribution_fee: u64, + pub search_keyword_fee: u64, +} diff --git a/packages/rs-platform-version/src/version/fee/data_contract_registration/v1.rs b/packages/rs-platform-version/src/version/fee/data_contract_registration/v1.rs new file mode 100644 index 00000000000..03950cf5d63 --- /dev/null +++ b/packages/rs-platform-version/src/version/fee/data_contract_registration/v1.rs @@ -0,0 +1,15 @@ +use crate::version::fee::data_contract_registration::FeeDataContractRegistrationVersion; + +// There were no fees for these things before Protocol version 9 (version 2.0) +pub const FEE_DATA_CONTRACT_REGISTRATION_VERSION1: FeeDataContractRegistrationVersion = + FeeDataContractRegistrationVersion { + base_contract_registration_fee: 0, + document_type_registration_fee: 0, + document_type_base_non_unique_index_registration_fee: 0, + document_type_base_unique_index_registration_fee: 0, + document_type_base_contested_index_registration_fee: 0, + token_registration_fee: 0, + token_uses_perpetual_distribution_fee: 0, + token_uses_pre_programmed_distribution_fee: 0, + search_keyword_fee: 0, + }; diff --git a/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs b/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs new file mode 100644 index 00000000000..e1bea5c57a1 --- /dev/null +++ b/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs @@ -0,0 +1,15 @@ +use crate::version::fee::data_contract_registration::FeeDataContractRegistrationVersion; + +/// Introduced in protocol version 9 (version 2.0) +pub const FEE_DATA_CONTRACT_REGISTRATION_VERSION2: FeeDataContractRegistrationVersion = + FeeDataContractRegistrationVersion { + base_contract_registration_fee: 10_000_000_000, // 0.1 Dash + document_type_registration_fee: 2_000_000_000, // 0.02 Dash + document_type_base_non_unique_index_registration_fee: 1_000_000_000, // 0.01 Dash + document_type_base_unique_index_registration_fee: 1_000_000_000, // 0.01 Dash + document_type_base_contested_index_registration_fee: 100_000_000_000, // 1 Dash + token_registration_fee: 10_000_000_000, // 0.1 Dash + token_uses_perpetual_distribution_fee: 10_000_000_000, // 0.1 Dash + token_uses_pre_programmed_distribution_fee: 10_000_000_000, // 0.1 Dash + search_keyword_fee: 10_000_000_000, // 0.1 Dash + }; diff --git a/packages/rs-platform-version/src/version/fee/data_contract_validation/mod.rs b/packages/rs-platform-version/src/version/fee/data_contract_validation/mod.rs new file mode 100644 index 00000000000..28ad0e6fb6b --- /dev/null +++ b/packages/rs-platform-version/src/version/fee/data_contract_validation/mod.rs @@ -0,0 +1,14 @@ +use bincode::{Decode, Encode}; + +pub mod v1; + +#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)] +pub struct FeeDataContractValidationVersion { + pub document_type_base_fee: u64, + pub document_type_schema_size_fee: u64, + pub document_type_per_property_fee: u64, + pub document_type_base_non_unique_index_fee: u64, + pub document_type_non_unique_index_per_property_fee: u64, + pub document_type_base_unique_index_fee: u64, + pub document_type_unique_index_per_property_fee: u64, +} diff --git a/packages/rs-platform-version/src/version/fee/data_contract/v1.rs b/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs similarity index 77% rename from packages/rs-platform-version/src/version/fee/data_contract/v1.rs rename to packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs index 516da472cfd..2c151ab1b2e 100644 --- a/packages/rs-platform-version/src/version/fee/data_contract/v1.rs +++ b/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs @@ -1,9 +1,9 @@ -use crate::version::fee::data_contract::FeeDataContractValidationVersion; +use crate::version::fee::data_contract_validation::FeeDataContractValidationVersion; pub const FEE_DATA_CONTRACT_VALIDATION_VERSION1: FeeDataContractValidationVersion = FeeDataContractValidationVersion { document_type_base_fee: 500, - document_type_size_fee: 10, + document_type_schema_size_fee: 10, document_type_per_property_fee: 40, document_type_base_non_unique_index_fee: 50, document_type_non_unique_index_per_property_fee: 30, diff --git a/packages/rs-platform-version/src/version/fee/mod.rs b/packages/rs-platform-version/src/version/fee/mod.rs index 735e1b51460..df0dc5a16d5 100644 --- a/packages/rs-platform-version/src/version/fee/mod.rs +++ b/packages/rs-platform-version/src/version/fee/mod.rs @@ -1,5 +1,7 @@ use crate::error::PlatformVersionError; -use crate::version::fee::data_contract::FeeDataContractValidationVersion; +use crate::version::fee::data_contract_registration::v1::FEE_DATA_CONTRACT_REGISTRATION_VERSION1; +use crate::version::fee::data_contract_registration::FeeDataContractRegistrationVersion; +use crate::version::fee::data_contract_validation::FeeDataContractValidationVersion; use crate::version::fee::hashing::FeeHashingVersion; use crate::version::fee::processing::{ FeeProcessingVersion, FeeProcessingVersionFieldsBeforeVersion1Point4, @@ -11,13 +13,15 @@ use crate::version::fee::v1::FEE_VERSION1; use crate::version::fee::vote_resolution_fund_fees::VoteResolutionFundFees; use bincode::{Decode, Encode}; -mod data_contract; +pub mod data_contract_registration; +mod data_contract_validation; mod hashing; mod processing; pub mod signature; pub mod state_transition_min_fees; pub mod storage; pub mod v1; +pub mod v2; pub mod vote_resolution_fund_fees; pub type FeeVersionNumber = u32; @@ -33,7 +37,8 @@ pub struct FeeVersion { pub signature: FeeSignatureVersion, pub hashing: FeeHashingVersion, pub processing: FeeProcessingVersion, - pub data_contract: FeeDataContractValidationVersion, + pub data_contract_validation: FeeDataContractValidationVersion, + pub data_contract_registration: FeeDataContractRegistrationVersion, pub state_transition_min_fees: StateTransitionMinFees, pub vote_resolution_fund_fees: VoteResolutionFundFees, } @@ -99,7 +104,8 @@ impl From for FeeVersion { signature: value.signature, hashing: value.hashing, processing: FeeProcessingVersion::from(value.processing), - data_contract: value.data_contract, + data_contract_validation: value.data_contract, + data_contract_registration: FEE_DATA_CONTRACT_REGISTRATION_VERSION1, state_transition_min_fees: value.state_transition_min_fees, vote_resolution_fund_fees: value.vote_resolution_fund_fees, } diff --git a/packages/rs-platform-version/src/version/fee/v1.rs b/packages/rs-platform-version/src/version/fee/v1.rs index fe43f0464c4..c77c9ec98b2 100644 --- a/packages/rs-platform-version/src/version/fee/v1.rs +++ b/packages/rs-platform-version/src/version/fee/v1.rs @@ -1,4 +1,5 @@ -use crate::version::fee::data_contract::v1::FEE_DATA_CONTRACT_VALIDATION_VERSION1; +use crate::version::fee::data_contract_registration::v1::FEE_DATA_CONTRACT_REGISTRATION_VERSION1; +use crate::version::fee::data_contract_validation::v1::FEE_DATA_CONTRACT_VALIDATION_VERSION1; use crate::version::fee::hashing::v1::FEE_HASHING_VERSION1; use crate::version::fee::processing::v1::FEE_PROCESSING_VERSION1; use crate::version::fee::signature::v1::FEE_SIGNATURE_VERSION1; @@ -14,7 +15,8 @@ pub const FEE_VERSION1: FeeVersion = FeeVersion { signature: FEE_SIGNATURE_VERSION1, hashing: FEE_HASHING_VERSION1, processing: FEE_PROCESSING_VERSION1, - data_contract: FEE_DATA_CONTRACT_VALIDATION_VERSION1, + data_contract_validation: FEE_DATA_CONTRACT_VALIDATION_VERSION1, + data_contract_registration: FEE_DATA_CONTRACT_REGISTRATION_VERSION1, state_transition_min_fees: STATE_TRANSITION_MIN_FEES_VERSION1, vote_resolution_fund_fees: VOTE_RESOLUTION_FUND_FEES_VERSION1, }; diff --git a/packages/rs-platform-version/src/version/fee/v2.rs b/packages/rs-platform-version/src/version/fee/v2.rs new file mode 100644 index 00000000000..fe82ac5534f --- /dev/null +++ b/packages/rs-platform-version/src/version/fee/v2.rs @@ -0,0 +1,23 @@ +use crate::version::fee::data_contract_registration::v2::FEE_DATA_CONTRACT_REGISTRATION_VERSION2; +use crate::version::fee::data_contract_validation::v1::FEE_DATA_CONTRACT_VALIDATION_VERSION1; +use crate::version::fee::hashing::v1::FEE_HASHING_VERSION1; +use crate::version::fee::processing::v1::FEE_PROCESSING_VERSION1; +use crate::version::fee::signature::v1::FEE_SIGNATURE_VERSION1; +use crate::version::fee::state_transition_min_fees::v1::STATE_TRANSITION_MIN_FEES_VERSION1; +use crate::version::fee::storage::v1::FEE_STORAGE_VERSION1; +use crate::version::fee::vote_resolution_fund_fees::v1::VOTE_RESOLUTION_FUND_FEES_VERSION1; +use crate::version::fee::FeeVersion; + +/// Introduced in protocol version 9 (2.0) +pub const FEE_VERSION2: FeeVersion = FeeVersion { + fee_version_number: 1, + uses_version_fee_multiplier_permille: Some(1000), //No action + storage: FEE_STORAGE_VERSION1, + signature: FEE_SIGNATURE_VERSION1, + hashing: FEE_HASHING_VERSION1, + processing: FEE_PROCESSING_VERSION1, + data_contract_validation: FEE_DATA_CONTRACT_VALIDATION_VERSION1, + data_contract_registration: FEE_DATA_CONTRACT_REGISTRATION_VERSION2, // changed to v2 + state_transition_min_fees: STATE_TRANSITION_MIN_FEES_VERSION1, + vote_resolution_fund_fees: VOTE_RESOLUTION_FUND_FEES_VERSION1, +}; diff --git a/packages/rs-platform-version/src/version/v9.rs b/packages/rs-platform-version/src/version/v9.rs index dbc3264fe55..95b7a01029f 100644 --- a/packages/rs-platform-version/src/version/v9.rs +++ b/packages/rs-platform-version/src/version/v9.rs @@ -21,7 +21,7 @@ use crate::version::drive_abci_versions::drive_abci_validation_versions::v6::DRI use crate::version::drive_abci_versions::drive_abci_withdrawal_constants::v2::DRIVE_ABCI_WITHDRAWAL_CONSTANTS_V2; use crate::version::drive_abci_versions::DriveAbciVersion; use crate::version::drive_versions::v4::DRIVE_VERSION_V4; -use crate::version::fee::v1::FEE_VERSION1; +use crate::version::fee::v2::FEE_VERSION2; use crate::version::protocol_version::PlatformVersion; use crate::version::system_data_contract_versions::v1::SYSTEM_DATA_CONTRACT_VERSIONS_V1; use crate::version::system_limits::v1::SYSTEM_LIMITS_V1; @@ -58,7 +58,7 @@ pub const PLATFORM_V9: PlatformVersion = PlatformVersion { factory_versions: DPP_FACTORY_VERSIONS_V1, }, system_data_contracts: SYSTEM_DATA_CONTRACT_VERSIONS_V1, - fee_version: FEE_VERSION1, + fee_version: FEE_VERSION2, //changed to have data contract pay registration fees system_limits: SYSTEM_LIMITS_V1, consensus: ConsensusVersions { tenderdash_consensus_version: 1, diff --git a/yarn.lock b/yarn.lock index c69a41f3f37..6f87bd9552a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4730,12 +4730,12 @@ __metadata: languageName: node linkType: hard -"base-x@npm:^3.0.2, base-x@npm:^3.0.6": - version: 3.0.9 - resolution: "base-x@npm:3.0.9" +"base-x@npm:^3.0.11": + version: 3.0.11 + resolution: "base-x@npm:3.0.11" dependencies: safe-buffer: "npm:^5.0.1" - checksum: 957101d6fd09e1903e846fd8f69fd7e5e3e50254383e61ab667c725866bec54e5ece5ba49ce385128ae48f9ec93a26567d1d5ebb91f4d56ef4a9cc0d5a5481e8 + checksum: c2e3c443fd07cb9b9d3e179a9e9c581daa31881005841fe8d6a834e534505890fedf03465ccf14512da60e3f7be00fe66167806b159ba076d2c03952ae7460c4 languageName: node linkType: hard