Skip to content

Commit

Permalink
more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
QuantumExplorer committed Jan 2, 2025
1 parent fbcfd6e commit 39e6d5d
Show file tree
Hide file tree
Showing 19 changed files with 782 additions and 40 deletions.
20 changes: 19 additions & 1 deletion packages/rs-dpp/src/data_contract/serialized_version/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0;
use crate::data_contract::{DataContract, DefinitionName, DocumentName};
use crate::data_contract::{
DataContract, DefinitionName, DocumentName, GroupContractPosition, TokenContractPosition,
EMPTY_GROUPS, EMPTY_TOKENS,
};
use crate::version::PlatformVersion;
use std::collections::BTreeMap;

use crate::data_contract::associated_token::token_configuration::TokenConfiguration;
use crate::data_contract::group::Group;
use crate::data_contract::serialized_version::v1::DataContractInSerializationFormatV1;
use crate::data_contract::v0::DataContractV0;
use crate::data_contract::v1::DataContractV1;
Expand Down Expand Up @@ -78,6 +83,19 @@ impl DataContractInSerializationFormat {
DataContractInSerializationFormat::V1(v1) => v1.version,
}
}

pub fn groups(&self) -> &BTreeMap<GroupContractPosition, Group> {
match self {
DataContractInSerializationFormat::V0(_) => &EMPTY_GROUPS,
DataContractInSerializationFormat::V1(v1) => &v1.groups,
}
}
pub fn tokens(&self) -> &BTreeMap<TokenContractPosition, TokenConfiguration> {
match self {
DataContractInSerializationFormat::V0(_) => &EMPTY_TOKENS,
DataContractInSerializationFormat::V1(v1) => &v1.tokens,
}
}
}

impl TryFromPlatformVersioned<DataContractV0> for DataContractInSerializationFormat {
Expand Down
10 changes: 4 additions & 6 deletions packages/rs-dpp/src/data_contract/v1/accessors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1S
use crate::data_contract::associated_token::token_configuration::TokenConfiguration;
use crate::data_contract::document_type::accessors::DocumentTypeV0Getters;
use crate::data_contract::group::Group;
use crate::tokens::calculate_token_id;
use crate::util::hash::hash_double;
use crate::ProtocolError;
use platform_value::Identifier;
Expand Down Expand Up @@ -173,12 +174,9 @@ impl DataContractV1Getters for DataContractV1 {

/// Returns the token id if a token exists at that position
fn token_id(&self, position: TokenContractPosition) -> Option<Identifier> {
self.tokens.get(&position).map(|_| {
let mut bytes = b"dash_token".to_vec();
bytes.extend_from_slice(self.id().as_bytes());
bytes.extend_from_slice(&position.to_be_bytes());
hash_double(bytes).into()
})
self.tokens
.get(&position)
.map(|_| calculate_token_id(self.id.as_bytes(), position).into())
}
}

Expand Down
19 changes: 15 additions & 4 deletions packages/rs-dpp/src/errors/consensus/basic/basic_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ use crate::consensus::basic::data_contract::{
IncompatibleRe2PatternError, InvalidCompoundIndexError, InvalidDataContractIdError,
InvalidDataContractVersionError, InvalidDocumentTypeNameError,
InvalidDocumentTypeRequiredSecurityLevelError, InvalidIndexPropertyTypeError,
InvalidIndexedPropertyConstraintError, SystemPropertyIndexAlreadyPresentError,
UndefinedIndexPropertyError, UniqueIndicesLimitReachedError,
UnknownDocumentCreationRestrictionModeError, UnknownSecurityLevelError,
UnknownStorageKeyRequirementsError, UnknownTradeModeError, UnknownTransferableTypeError,
InvalidIndexedPropertyConstraintError, InvalidTokenBaseSupplyError,
NonContiguousContractGroupPositionsError, NonContiguousContractTokenPositionsError,
SystemPropertyIndexAlreadyPresentError, UndefinedIndexPropertyError,
UniqueIndicesLimitReachedError, UnknownDocumentCreationRestrictionModeError,
UnknownSecurityLevelError, UnknownStorageKeyRequirementsError, UnknownTradeModeError,
UnknownTransferableTypeError,
};
use crate::consensus::basic::decode::{
ProtocolVersionParsingError, SerializedObjectParsingError, VersionError,
Expand Down Expand Up @@ -199,6 +201,15 @@ pub enum BasicError {
#[error(transparent)]
DataContractHaveNewUniqueIndexError(DataContractHaveNewUniqueIndexError),

#[error(transparent)]
NonContiguousContractTokenPositionsError(NonContiguousContractTokenPositionsError),

#[error(transparent)]
NonContiguousContractGroupPositionsError(NonContiguousContractGroupPositionsError),

#[error(transparent)]
InvalidTokenBaseSupplyError(InvalidTokenBaseSupplyError),

// Document
#[error(transparent)]
DataContractNotPresentError(DataContractNotPresentError),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::consensus::basic::BasicError;
use crate::errors::ProtocolError;
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
use thiserror::Error;

use crate::consensus::ConsensusError;

use bincode::{Decode, Encode};
#[derive(
Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize,
)]
#[error(
"Invalid token base supply. Given base supply: {}, Max allowed base supply: {}",
base_supply,
i64::MAX
)]
#[platform_serialize(unversioned)]
pub struct InvalidTokenBaseSupplyError {
/*
DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION
*/
base_supply: u64,
}

impl InvalidTokenBaseSupplyError {
pub fn new(base_supply: u64) -> Self {
Self { base_supply }
}

pub fn base_supply(&self) -> u64 {
self.base_supply
}
}

impl From<InvalidTokenBaseSupplyError> for ConsensusError {
fn from(err: InvalidTokenBaseSupplyError) -> Self {
Self::BasicError(BasicError::InvalidTokenBaseSupplyError(err))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ mod invalid_index_property_type_error;
mod invalid_indexed_property_constraint_error;
#[cfg(feature = "json-schema-validation")]
mod invalid_json_schema_ref_error;
mod invalid_token_base_supply_error;
mod non_contiguous_contract_group_positions_error;
mod non_contiguous_contract_token_positions_error;
mod system_property_index_already_present_error;
mod undefined_index_property_error;
mod unique_indices_limit_reached_error;
Expand Down Expand Up @@ -57,6 +60,9 @@ pub use contested_unique_index_on_mutable_document_type_error::*;
pub use contested_unique_index_with_unique_index_error::*;
pub use incompatible_document_type_schema_error::*;
pub use invalid_document_type_name_error::*;
pub use invalid_token_base_supply_error::*;
pub use non_contiguous_contract_group_positions_error::*;
pub use non_contiguous_contract_token_positions_error::*;
pub use unknown_document_creation_restriction_mode_error::*;
pub use unknown_security_level_error::*;
pub use unknown_storage_key_requirements_error::*;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::consensus::basic::BasicError;
use crate::consensus::ConsensusError;
use crate::data_contract::GroupContractPosition;
use crate::errors::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(
"Contract Group Positions are not contiguous. Missing position: {}, Followed position: {}",
missing_position,
followed_position
)]
#[platform_serialize(unversioned)]
pub struct NonContiguousContractGroupPositionsError {
/*
DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION
*/
missing_position: GroupContractPosition,
followed_position: GroupContractPosition,
}

impl NonContiguousContractGroupPositionsError {
pub fn new(
missing_position: GroupContractPosition,
followed_position: GroupContractPosition,
) -> Self {
Self {
missing_position,
followed_position,
}
}

pub fn missing_position(&self) -> u16 {
self.missing_position
}

pub fn followed_position(&self) -> u16 {
self.followed_position
}
}

impl From<NonContiguousContractGroupPositionsError> for ConsensusError {
fn from(err: NonContiguousContractGroupPositionsError) -> Self {
Self::BasicError(BasicError::NonContiguousContractGroupPositionsError(err))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::consensus::basic::BasicError;
use crate::consensus::ConsensusError;
use crate::data_contract::TokenContractPosition;
use crate::errors::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(
"Contract Token Positions are not contiguous. Missing position: {}, Followed position: {}",
missing_position,
followed_position
)]
#[platform_serialize(unversioned)]
pub struct NonContiguousContractTokenPositionsError {
/*
DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION
*/
missing_position: TokenContractPosition,
followed_position: TokenContractPosition,
}

impl NonContiguousContractTokenPositionsError {
pub fn new(
missing_position: TokenContractPosition,
followed_position: TokenContractPosition,
) -> Self {
Self {
missing_position,
followed_position,
}
}

pub fn missing_position(&self) -> u16 {
self.missing_position
}

pub fn followed_position(&self) -> u16 {
self.followed_position
}
}

impl From<NonContiguousContractTokenPositionsError> for ConsensusError {
fn from(err: NonContiguousContractTokenPositionsError) -> Self {
Self::BasicError(BasicError::NonContiguousContractTokenPositionsError(err))
}
}
3 changes: 3 additions & 0 deletions packages/rs-dpp/src/errors/consensus/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ impl ErrorWithCode for BasicError {
Self::ContestedUniqueIndexOnMutableDocumentTypeError(_) => 10248,
Self::ContestedUniqueIndexWithUniqueIndexError(_) => 10249,
Self::DataContractTokenConfigurationUpdateError { .. } => 10250,
Self::InvalidTokenBaseSupplyError(_) => 10251,
Self::NonContiguousContractGroupPositionsError(_) => 10252,
Self::NonContiguousContractTokenPositionsError(_) => 10253,

// Document Errors: 10400-10449
Self::DataContractNotPresentError { .. } => 10400,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::data_contract::GroupContractPosition;
use crate::group::GroupStateTransitionInfo;
use crate::prelude::IdentityNonce;
use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0;
use crate::tokens::calculate_token_id;
use crate::util::hash::hash_double;
use platform_value::Identifier;

Expand All @@ -19,10 +20,11 @@ pub trait TokenBaseTransitionV0Methods {

/// Calculates the token ID.
fn calculate_token_id(&self) -> Identifier {
let mut bytes = b"token".to_vec();
bytes.extend_from_slice(self.data_contract_id().as_bytes());
bytes.extend_from_slice(&self.token_contract_position().to_be_bytes());
hash_double(bytes).into()
calculate_token_id(
self.data_contract_id().as_bytes(),
self.token_contract_position(),
)
.into()
}

/// Returns the token ID.
Expand Down
9 changes: 9 additions & 0 deletions packages/rs-dpp/src/tokens/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
use crate::data_contract::TokenContractPosition;
use crate::util::hash::hash_double;

pub mod allowed_currency;
pub mod errors;
pub mod token_event;
pub fn calculate_token_id(contract_id: &[u8; 32], token_pos: TokenContractPosition) -> [u8; 32] {
let mut bytes = b"dash_token".to_vec();
bytes.extend_from_slice(contract_id);
bytes.extend_from_slice(&token_pos.to_be_bytes());
hash_double(bytes)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ use crate::execution::types::state_transition_execution_context::{
StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0,
};
use dpp::consensus::basic::data_contract::{
InvalidDataContractIdError, InvalidDataContractVersionError,
InvalidDataContractIdError, InvalidDataContractVersionError, InvalidTokenBaseSupplyError,
NonContiguousContractTokenPositionsError,
};
use dpp::consensus::basic::BasicError;
use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters;
use dpp::data_contract::INITIAL_DATA_CONTRACT_VERSION;
use dpp::prelude::DataContract;
use dpp::state_transition::data_contract_create_transition::accessors::DataContractCreateTransitionAccessorsV0;
Expand Down Expand Up @@ -67,6 +69,38 @@ impl DataContractCreatedStateTransitionAdvancedStructureValidationV0
));
}

let expected_position = 0;

for (token_contract_position, token_configuration) in self.data_contract().tokens() {
if expected_position != *token_contract_position {
let bump_action = StateTransitionAction::BumpIdentityNonceAction(
BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self),
);

return Ok(ConsensusValidationResult::new_with_data_and_errors(
bump_action,
vec![NonContiguousContractTokenPositionsError::new(
expected_position,
*token_contract_position,
)
.into()],
));
}

if token_configuration.base_supply() > i64::MAX as u64 {
let bump_action = StateTransitionAction::BumpIdentityNonceAction(
BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self),
);

return Ok(ConsensusValidationResult::new_with_data_and_errors(
bump_action,
vec![
InvalidTokenBaseSupplyError::new(token_configuration.base_supply()).into(),
],
));
}
}

Ok(ConsensusValidationResult::default())
}
}
Expand Down
Loading

0 comments on commit 39e6d5d

Please sign in to comment.