Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
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, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default

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, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default

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, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default

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, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default
};
use crate::data_contract::associated_token::token_configuration_convention::accessors::v0::TokenConfigurationConventionV0Getters;
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;

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)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// 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;
}
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 @@ -3,6 +3,8 @@ use bincode::{Decode, Encode};
use derive_more::From;
use serde::{Deserialize, Serialize};

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,3 +1,4 @@
use crate::data_contract::associated_token::token_configuration_convention::accessors::v0::TokenConfigurationConventionV0Getters;
use bincode::Encode;
use platform_serialization::de::Decode;
use serde::{Deserialize, Serialize};
Expand All @@ -22,11 +23,15 @@ impl fmt::Display for TokenConfigurationLocalizationsV0 {
}
}

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, TokenConfigurationLocalizationsV0>,
#[serde(default = "default_decimals")]
Expand Down Expand Up @@ -54,3 +59,19 @@ 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)
}
}
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 @@ -74,7 +74,7 @@ use crate::consensus::basic::overflow_error::OverflowError;
use crate::consensus::basic::token::{
ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError,
DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenIdError,
InvalidTokenPositionError, TokenTransferToOurselfError,
InvalidTokenPositionError, MissingDefaultLocalizationError, TokenTransferToOurselfError,
};
use crate::consensus::basic::unsupported_version_error::UnsupportedVersionError;
use crate::consensus::basic::value_error::ValueError;
Expand Down Expand Up @@ -469,6 +469,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 @@ -4,6 +4,7 @@ mod destination_identity_for_token_minting_not_set_error;
mod invalid_action_id_error;
mod invalid_token_id_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 @@ -12,4 +13,5 @@ pub use destination_identity_for_token_minting_not_set_error::*;
pub use invalid_action_id_error::*;
pub use invalid_token_id_error::*;
pub use invalid_token_position_error::*;
pub use missing_default_localization::*;
pub use token_transfer_to_ourselves_error::*;
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 @@ -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
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, InvalidTokenIdError, InvalidTokenPositionError, TokenTransferToOurselfError};
use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenIdError, 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 @@ -690,6 +690,9 @@ fn from_basic_error(basic_error: &BasicError) -> JsValue {
)
.into()
}
BasicError::MissingDefaultLocalizationError(e) => {
generic_consensus_error!(MissingDefaultLocalizationError, e).into()
}
}
}

Expand Down
Loading