Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 (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, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^

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, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
};
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 (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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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 @@ -288,13 +288,13 @@ describe('Token History Contract', () => {
});

describe('tokenId', () => {
it('should be 32 bytes', async () => {
rawUnfreezeDocument.tokenId = crypto.randomBytes(33);
it('should be defined', async () => {
delete rawUnfreezeDocument.tokenId;
const document = dpp.document.create(dataContract, identityId, 'unfreeze', rawUnfreezeDocument);
const validationResult = document.validate(dpp.protocolVersion);
const error = expectJsonSchemaError(validationResult);
expect(error.keyword).to.equal('maxItems');
expect(error.instancePath).to.equal('/tokenId');
expect(error.keyword).to.equal('required');
expect(error.params.missingProperty).to.equal('tokenId');
});
});

Expand Down 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