Skip to content

fix(drive-abci): make sure identities in token config exist #2583

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 1, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ impl TokenConfigurationV0Getters for TokenConfiguration {
}
}

/// Returns all the change contract rules, including those from the distribution rules
fn all_change_control_rules(&self) -> Vec<(&str, &ChangeControlRules)> {
match self {
TokenConfiguration::V0(v0) => v0.all_change_control_rules(),
}
}

/// Returns the token description.
fn description(&self) -> &Option<String> {
match self {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ pub trait TokenConfigurationV0Getters {
/// Returns all group positions used in the token configuration
fn all_used_group_positions(&self) -> BTreeSet<GroupContractPosition>;

/// Returns all the change contract rules, including those from the distribution rules
fn all_change_control_rules(&self) -> Vec<(&str, &ChangeControlRules)>;

/// Returns the token description.
fn description(&self) -> &Option<String>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,41 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 {
group_positions
}

fn all_change_control_rules(&self) -> Vec<(&str, &ChangeControlRules)> {
vec![
("max_supply_change_rules", &self.max_supply_change_rules),
("conventions_change_rules", &self.conventions_change_rules),
(
"distribution_rules.new_tokens_destination_identity_rules",
self.distribution_rules
.new_tokens_destination_identity_rules(),
),
(
"distribution_rules.minting_allow_choosing_destination_rules",
self.distribution_rules
.minting_allow_choosing_destination_rules(),
),
(
"distribution_rules.perpetual_distribution_rules",
self.distribution_rules.perpetual_distribution_rules(),
),
(
"distribution_rules.change_direct_purchase_pricing_rules",
self.distribution_rules
.change_direct_purchase_pricing_rules(),
),
("manual_minting_rules", &self.manual_minting_rules),
("manual_burning_rules", &self.manual_burning_rules),
("freeze_rules", &self.freeze_rules),
("unfreeze_rules", &self.unfreeze_rules),
(
"destroy_frozen_funds_rules",
&self.destroy_frozen_funds_rules,
),
("emergency_action_rules", &self.emergency_action_rules),
]
}

/// Returns the token description.
fn description(&self) -> &Option<String> {
&self.description
Expand Down
9 changes: 5 additions & 4 deletions packages/rs-dpp/src/errors/consensus/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ impl ErrorWithCode for StateError {
Self::DataContractConfigUpdateError { .. } => 40002,
Self::DataContractUpdatePermissionError(_) => 40003,
Self::DataContractUpdateActionNotAllowedError(_) => 40004,
Self::PreProgrammedDistributionTimestampInPastError(_) => 40005,
Self::IdentityInTokenConfigurationNotFoundError(_) => 40006,

// Document Errors: 40100-40199
Self::DocumentAlreadyPresentError { .. } => 40100,
Expand Down Expand Up @@ -310,10 +312,9 @@ impl ErrorWithCode for StateError {
Self::InvalidTokenClaimNoCurrentRewards(_) => 40716,
Self::InvalidTokenClaimWrongClaimant(_) => 40717,
Self::TokenTransferRecipientIdentityNotExistError(_) => 40718,
Self::PreProgrammedDistributionTimestampInPastError(_) => 40719,
Self::TokenDirectPurchaseUserPriceTooLow(_) => 40720,
Self::TokenAmountUnderMinimumSaleAmount(_) => 40721,
Self::TokenNotForDirectSale(_) => 40722,
Self::TokenDirectPurchaseUserPriceTooLow(_) => 40719,
Self::TokenAmountUnderMinimumSaleAmount(_) => 40720,
Self::TokenNotForDirectSale(_) => 40721,

// Group errors: 40800-40899
Self::IdentityNotMemberOfGroupError(_) => 40800,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use crate::consensus::state::state_error::StateError;
use crate::consensus::ConsensusError;
use crate::ProtocolError;
use bincode::{Decode, Encode};
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
use platform_value::Identifier;
use thiserror::Error;

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize)]
#[platform_serialize(unversioned)]
pub enum TokenConfigurationIdentityContext {
ChangeControlRule(String),
DefaultMintingRecipient,
PerpetualDistributionRecipient,
PreProgrammedDistributionRecipient,
}

#[derive(
Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize,
)]
#[error("Identity {identity_id} required in token position {token_position} of contract {contract_id} for {context:?} does not exist")]
#[platform_serialize(unversioned)]
pub struct IdentityInTokenConfigurationNotFoundError {
contract_id: Identifier,
token_position: u16,
context: TokenConfigurationIdentityContext,
identity_id: Identifier,
}

impl IdentityInTokenConfigurationNotFoundError {
pub fn new(
contract_id: Identifier,
token_position: u16,
context: TokenConfigurationIdentityContext,
identity_id: Identifier,
) -> Self {
Self {
contract_id,
token_position,
context,
identity_id,
}
}

pub fn contract_id(&self) -> &Identifier {
&self.contract_id
}

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

pub fn context(&self) -> &TokenConfigurationIdentityContext {
&self.context
}

pub fn identity_id(&self) -> &Identifier {
&self.identity_id
}
}

impl From<IdentityInTokenConfigurationNotFoundError> for ConsensusError {
fn from(err: IdentityInTokenConfigurationNotFoundError) -> Self {
Self::StateError(StateError::IdentityInTokenConfigurationNotFoundError(err))
}
}
2 changes: 2 additions & 0 deletions packages/rs-dpp/src/errors/consensus/state/identity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ pub mod missing_identity_public_key_ids_error;
pub mod missing_transfer_key_error;
pub mod no_transfer_key_for_core_withdrawal_available_error;

pub mod identity_for_token_configuration_not_found_error;
mod recipient_identity_does_not_exist_error;

pub use recipient_identity_does_not_exist_error::*;
4 changes: 4 additions & 0 deletions packages/rs-dpp/src/errors/consensus/state/state_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::consensus::state::document::document_contest_not_paid_for_error::Docu
use crate::consensus::state::document::document_incorrect_purchase_price_error::DocumentIncorrectPurchasePriceError;
use crate::consensus::state::document::document_not_for_sale_error::DocumentNotForSaleError;
use crate::consensus::state::group::{GroupActionAlreadyCompletedError, GroupActionAlreadySignedByIdentityError, GroupActionDoesNotExistError, IdentityNotMemberOfGroupError};
use crate::consensus::state::identity::identity_for_token_configuration_not_found_error::IdentityInTokenConfigurationNotFoundError;
use crate::consensus::state::identity::identity_public_key_already_exists_for_unique_contract_bounds_error::IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError;
use crate::consensus::state::identity::invalid_identity_contract_nonce_error::InvalidIdentityNonceError;
use crate::consensus::state::identity::missing_transfer_key_error::MissingTransferKeyError;
Expand Down Expand Up @@ -298,6 +299,9 @@ pub enum StateError {

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

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

impl From<StateError> for ConsensusError {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ mod random {

#[test]
#[ignore]
fn test_block_based_perpetual_random_0_MAX_distribution_param() {
fn test_block_based_perpetual_random_0_max_distribution_param() {
check_heights(
DistributionFunction::Random {
min: 0,
Expand Down
Loading