Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests-rs-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ jobs:
check_each_feature:
name: Check each feature
runs-on: ubuntu-24.04
timeout-minutes: 10
timeout-minutes: 15
if: ${{ inputs.check-each-feature }}
steps:
- name: Check out repo
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,45 @@
mod v0;
pub mod v0;

use crate::data_contract::associated_token::token_configuration::accessors::v0::{
TokenConfigurationV0Getters, TokenConfigurationV0Setters,

Check warning on line 4 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (dash-sdk) / Linting

unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters`

warning: unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs:4:5 | 4 | TokenConfigurationV0Getters, TokenConfigurationV0Setters, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 4 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (drive) / Linting

unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters`

warning: unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs:4:5 | 4 | TokenConfigurationV0Getters, TokenConfigurationV0Setters, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 4 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (drive-abci) / Linting

unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters`

warning: unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs:4:5 | 4 | TokenConfigurationV0Getters, TokenConfigurationV0Setters, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 4 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (wasm-dpp) / Linting

unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters`

warning: unused imports: `TokenConfigurationV0Getters` and `TokenConfigurationV0Setters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs:4:5 | 4 | TokenConfigurationV0Getters, TokenConfigurationV0Setters, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
};
use crate::data_contract::associated_token::token_configuration_convention::accessors::v0::TokenConfigurationConventionV0Getters;
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;
use crate::data_contract::associated_token::token_configuration_localization::TokenConfigurationLocalization;
use std::collections::BTreeMap;

impl TokenConfigurationConventionV0Getters for TokenConfigurationConvention {
fn singular_form_by_language_code_or_default(&self, language_code: &str) -> &str {
match self {
TokenConfigurationConvention::V0(v0) => {
v0.singular_form_by_language_code_or_default(language_code)
}
}
}

fn plural_form_by_language_code_or_default(&self, language_code: &str) -> &str {
match self {
TokenConfigurationConvention::V0(v0) => {
v0.plural_form_by_language_code_or_default(language_code)
}
}
}

fn localizations(&self) -> &BTreeMap<String, TokenConfigurationLocalization> {
match self {
TokenConfigurationConvention::V0(v0) => v0.localizations(),
}
}

fn localizations_mut(&mut self) -> &mut BTreeMap<String, TokenConfigurationLocalization> {
match self {
TokenConfigurationConvention::V0(v0) => v0.localizations_mut(),
}
}

fn decimals(&self) -> u16 {
match self {
TokenConfigurationConvention::V0(v0) => v0.decimals(),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use std::collections::BTreeMap;

/// Accessor trait for getters of `TokenConfigurationConventionV0`
pub trait TokenConfigurationConventionV0Getters {
/// Returns the localized token name in singular form
fn singular_form_by_language_code_or_default(&self, language_code: &str) -> &str;
/// Returns the localized token name in plural form
fn plural_form_by_language_code_or_default(&self, language_code: &str) -> &str;
/// Returns a reference to the localizations.
fn localizations(&self) -> &BTreeMap<String, TokenConfigurationLocalization>;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod validate_localizations;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;
use crate::validation::SimpleConsensusValidationResult;
use crate::ProtocolError;
use platform_version::version::PlatformVersion;

mod v0;

impl TokenConfigurationConvention {
pub fn validate_localizations(
&self,
platform_version: &PlatformVersion,
) -> Result<SimpleConsensusValidationResult, ProtocolError> {
match platform_version
.dpp
.validation
.data_contract
.validate_localizations
{
0 => Ok(self.validate_localizations_v0()),
version => Err(ProtocolError::UnknownVersionMismatch {
method: "validate_localizations".to_string(),
known_versions: vec![0],
received: version,
}),
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::consensus::basic::token::MissingDefaultLocalizationError;
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;
use crate::validation::SimpleConsensusValidationResult;

impl TokenConfigurationConvention {
#[inline(always)]
pub(super) fn validate_localizations_v0(&self) -> SimpleConsensusValidationResult {
let english_localization = match self {
TokenConfigurationConvention::V0(v0) => v0.localizations.get("en"),
};

// If there is no English localization, return an error
if english_localization.is_none() {
return SimpleConsensusValidationResult::new_with_error(
MissingDefaultLocalizationError::new().into(),
);
}

// If we reach here with no errors, return an empty result
SimpleConsensusValidationResult::new()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
use std::fmt;

mod accessors;
mod methods;
pub mod v0;

#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, PartialOrd, From)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
use crate::data_contract::associated_token::token_configuration_convention::accessors::v0::TokenConfigurationConventionV0Getters;
use crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters;
use crate::data_contract::associated_token::token_configuration_localization::TokenConfigurationLocalization;
use bincode::Encode;
use platform_serialization::de::Decode;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt;

pub const ENGLISH_ISO_639: &str = "en";

#[derive(
Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, PartialOrd, Default,
)]
#[serde(rename_all = "camelCase")]
pub struct TokenConfigurationConventionV0 {
/// Localizations for the token name.
/// The key must be a ISO 639 2-chars language code
#[serde(default)]
pub localizations: BTreeMap<String, TokenConfigurationLocalization>,
#[serde(default = "default_decimals")]
Expand Down Expand Up @@ -37,3 +43,31 @@ impl fmt::Display for TokenConfigurationConventionV0 {
)
}
}

impl TokenConfigurationConventionV0Getters for TokenConfigurationConventionV0 {
fn singular_form_by_language_code_or_default(&self, language_code: &str) -> &str {
self.localizations
.get(language_code)
.map(|localization| localization.singular_form())
.unwrap_or_else(|| self.localizations[ENGLISH_ISO_639].singular_form())
}

fn plural_form_by_language_code_or_default(&self, language_code: &str) -> &str {
self.localizations
.get(language_code)
.map(|localization| localization.plural_form())
.unwrap_or_else(|| self.localizations[ENGLISH_ISO_639].plural_form())
}

fn localizations(&self) -> &BTreeMap<String, TokenConfigurationLocalization> {
&self.localizations
}

fn localizations_mut(&mut self) -> &mut BTreeMap<String, TokenConfigurationLocalization> {
&mut self.localizations
}

fn decimals(&self) -> u16 {
self.decimals
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters;

Check warning on line 1 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (dash-sdk) / Linting

unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters`

warning: unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs:1:5 | 1 | use crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 1 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (drive) / Linting

unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters`

warning: unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs:1:5 | 1 | use crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 1 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (drive-abci) / Linting

unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters`

warning: unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs:1:5 | 1 | use crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 1 in packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (wasm-dpp) / Linting

unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters`

warning: unused import: `crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters` --> packages/rs-dpp/src/data_contract/associated_token/token_configuration_localization/mod.rs:1:5 | 1 | use crate::data_contract::associated_token::token_configuration_localization::accessors::v0::TokenConfigurationLocalizationV0Getters; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
use crate::data_contract::associated_token::token_configuration_localization::v0::TokenConfigurationLocalizationV0;
use bincode::Encode;
use derive_more::From;
Expand Down
5 changes: 4 additions & 1 deletion packages/rs-dpp/src/errors/consensus/basic/basic_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ use crate::consensus::basic::token::{
ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError,
DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenAmountError,
InvalidTokenConfigUpdateNoChangeError, InvalidTokenIdError, InvalidTokenNoteTooBigError,
InvalidTokenPositionError, TokenTransferToOurselfError,
InvalidTokenPositionError, MissingDefaultLocalizationError, TokenTransferToOurselfError,
};
use crate::consensus::basic::unsupported_version_error::UnsupportedVersionError;
use crate::consensus::basic::value_error::ValueError;
Expand Down Expand Up @@ -503,6 +503,9 @@ pub enum BasicError {
GroupNonUnilateralMemberPowerHasLessThanRequiredPowerError(
GroupNonUnilateralMemberPowerHasLessThanRequiredPowerError,
),

#[error(transparent)]
MissingDefaultLocalizationError(MissingDefaultLocalizationError),
}

impl From<BasicError> for ConsensusError {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::consensus::basic::BasicError;
use crate::consensus::ConsensusError;
use crate::ProtocolError;
use bincode::{Decode, Encode};
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
use thiserror::Error;
#[derive(
Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize,
)]
#[error("Missing english ('en') localization which is using by default")]
#[platform_serialize(unversioned)]
pub struct MissingDefaultLocalizationError {}

impl MissingDefaultLocalizationError {
pub fn new() -> Self {
Self {}
}
}

impl From<MissingDefaultLocalizationError> for ConsensusError {
fn from(err: MissingDefaultLocalizationError) -> Self {
Self::BasicError(BasicError::MissingDefaultLocalizationError(err))
}
}
2 changes: 2 additions & 0 deletions packages/rs-dpp/src/errors/consensus/basic/token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod invalid_token_config_update_no_change_error;
mod invalid_token_id_error;
mod invalid_token_note_too_big_error;
mod invalid_token_position_error;
mod missing_default_localization;
mod token_transfer_to_ourselves_error;

pub use choosing_token_mint_recipient_not_allowed_error::*;
Expand All @@ -18,4 +19,5 @@ pub use invalid_token_config_update_no_change_error::*;
pub use invalid_token_id_error::*;
pub use invalid_token_note_too_big_error::*;
pub use invalid_token_position_error::*;
pub use missing_default_localization::*;
pub use token_transfer_to_ourselves_error::*;
7 changes: 4 additions & 3 deletions packages/rs-dpp/src/errors/consensus/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ impl ErrorWithCode for BasicError {
Self::NonContiguousContractGroupPositionsError(_) => 10252,
Self::NonContiguousContractTokenPositionsError(_) => 10253,
Self::InvalidTokenDistributionFunctionDivideByZeroError(_) => 10254,
Self::InvalidTokenDistributionFunctionInvalidParameterError(_) => 10254,
Self::InvalidTokenDistributionFunctionInvalidParameterTupleError(_) => 10255,
Self::InvalidTokenDistributionFunctionIncoherenceError(_) => 10256,
Self::InvalidTokenDistributionFunctionInvalidParameterError(_) => 10255,
Self::InvalidTokenDistributionFunctionInvalidParameterTupleError(_) => 10256,
Self::InvalidTokenDistributionFunctionIncoherenceError(_) => 10257,
Self::MissingDefaultLocalizationError(_) => 10258,

// Group Errors: 10350-10399
Self::GroupPositionDoesNotExistError(_) => 10350,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ impl DataContractCreatedStateTransitionAdvancedStructureValidationV0
));
}

let validation_result = token_configuration
.conventions()
.validate_localizations(platform_version)?;
if !validation_result.is_valid() {
let bump_action = StateTransitionAction::BumpIdentityNonceAction(
BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self),
);

return Ok(ConsensusValidationResult::new_with_data_and_errors(
bump_action,
validation_result.errors,
));
}

let validation_result = token_configuration.validate_token_config_groups_exist(
self.data_contract().groups(),
platform_version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@
"$format_version": "0",
"conventions": {
"$format_version": "0",
"localizations": {
"en": {
"$format_version": "0",
"shouldCapitalize": false,
"pluralForm": "tests",
"singularForm": "test"
}
},
"decimals": 8
},
"baseSupply": 100000,
"maxSupply": null
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct DataContractValidationVersions {
pub validate_not_defined_properties: FeatureVersion,
pub validate_property_definition: FeatureVersion,
pub validate_token_config_groups_exist: FeatureVersion,
pub validate_localizations: FeatureVersion,
}

#[derive(Clone, Debug, Default)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub const DPP_VALIDATION_VERSIONS_V1: DPPValidationVersions = DPPValidationVersi
validate_not_defined_properties: 0,
validate_property_definition: 0,
validate_token_config_groups_exist: 0,
validate_localizations: 0,
},
document_type: DocumentTypeValidationVersions {
validate_update: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub const DPP_VALIDATION_VERSIONS_V2: DPPValidationVersions = DPPValidationVersi
validate_not_defined_properties: 0,
validate_property_definition: 0,
validate_token_config_groups_exist: 0,
validate_localizations: 0,
},
document_type: DocumentTypeValidationVersions {
validate_update: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ describe('Token History Contract', () => {
const document = dpp.document.create(dataContract, identityId, 'emergencyAction', rawEmergencyActionDocument);
const validationResult = document.validate(dpp.protocolVersion);
const error = expectJsonSchemaError(validationResult);
expect(error.keyword).to.equal('minimum');
expect(error.keyword).to.equal('enum');
});
});

Expand Down
5 changes: 4 additions & 1 deletion packages/wasm-dpp/src/errors/consensus/consensus_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use dpp::consensus::basic::document::{ContestedDocumentsTemporarilyNotAllowedErr
use dpp::consensus::basic::group::GroupActionNotAllowedOnTransitionError;
use dpp::consensus::basic::identity::{DataContractBoundsNotPresentError, DisablingKeyIdAlsoBeingAddedInSameTransitionError, InvalidIdentityCreditWithdrawalTransitionAmountError, InvalidIdentityUpdateTransitionDisableKeysError, InvalidIdentityUpdateTransitionEmptyError, TooManyMasterPublicKeyError, WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError};
use dpp::consensus::basic::overflow_error::OverflowError;
use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenAmountError, InvalidTokenConfigUpdateNoChangeError, InvalidTokenIdError, InvalidTokenNoteTooBigError, InvalidTokenPositionError, TokenTransferToOurselfError};
use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenAmountError, InvalidTokenConfigUpdateNoChangeError, InvalidTokenIdError, InvalidTokenNoteTooBigError, InvalidTokenPositionError, MissingDefaultLocalizationError, TokenTransferToOurselfError};
use dpp::consensus::state::data_contract::data_contract_update_action_not_allowed_error::DataContractUpdateActionNotAllowedError;
use dpp::consensus::state::data_contract::document_type_update_error::DocumentTypeUpdateError;
use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError;
Expand Down Expand Up @@ -728,6 +728,9 @@ fn from_basic_error(basic_error: &BasicError) -> JsValue {
BasicError::InvalidTokenNoteTooBigError(e) => {
generic_consensus_error!(InvalidTokenNoteTooBigError, e).into()
}
BasicError::MissingDefaultLocalizationError(e) => {
generic_consensus_error!(MissingDefaultLocalizationError, e).into()
}
}
}

Expand Down
Loading