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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::data_contract::document_type::restricted_creation::CreationRestrictio
#[cfg(feature = "validation")]
use crate::data_contract::document_type::validator::StatelessJsonSchemaLazyValidator;
use crate::data_contract::storage_requirements::keys_for_document_type::StorageKeyRequirements;
use crate::data_contract::TokenContractPosition;
use crate::document::transfer::Transferable;
use crate::identity::SecurityLevel;
use crate::nft::TradeMode;
Expand Down Expand Up @@ -625,6 +626,22 @@ impl DocumentTypeV1Getters for DocumentType {
DocumentType::V1(v1) => v1.document_purchase_token_cost(),
}
}

fn all_document_token_costs(&self) -> Vec<&DocumentActionTokenCost> {
match self {
DocumentType::V0(_) => vec![],
DocumentType::V1(v1) => v1.all_document_token_costs(),
}
}

fn all_external_token_costs_contract_tokens(
&self,
) -> BTreeMap<Identifier, BTreeSet<TokenContractPosition>> {
match self {
DocumentType::V0(_) => BTreeMap::new(),
DocumentType::V1(v1) => v1.all_external_token_costs_contract_tokens(),
}
}
}

impl DocumentTypeV1Getters for DocumentTypeRef<'_> {
Expand Down Expand Up @@ -669,6 +686,22 @@ impl DocumentTypeV1Getters for DocumentTypeRef<'_> {
DocumentTypeRef::V1(v1) => v1.document_purchase_token_cost(),
}
}

fn all_document_token_costs(&self) -> Vec<&DocumentActionTokenCost> {
match self {
DocumentTypeRef::V0(_) => vec![],
DocumentTypeRef::V1(v1) => v1.all_document_token_costs(),
}
}

fn all_external_token_costs_contract_tokens(
&self,
) -> BTreeMap<Identifier, BTreeSet<TokenContractPosition>> {
match self {
DocumentTypeRef::V0(_) => BTreeMap::new(),
DocumentTypeRef::V1(v1) => v1.all_external_token_costs_contract_tokens(),
}
}
}

impl DocumentTypeV1Getters for DocumentTypeMutRef<'_> {
Expand Down Expand Up @@ -713,4 +746,20 @@ impl DocumentTypeV1Getters for DocumentTypeMutRef<'_> {
DocumentTypeMutRef::V1(v1) => v1.document_purchase_token_cost(),
}
}

fn all_document_token_costs(&self) -> Vec<&DocumentActionTokenCost> {
match self {
DocumentTypeMutRef::V0(_) => vec![],
DocumentTypeMutRef::V1(v1) => v1.all_document_token_costs(),
}
}

fn all_external_token_costs_contract_tokens(
&self,
) -> BTreeMap<Identifier, BTreeSet<TokenContractPosition>> {
match self {
DocumentTypeMutRef::V0(_) => BTreeMap::new(),
DocumentTypeMutRef::V1(v1) => v1.all_external_token_costs_contract_tokens(),
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::data_contract::TokenContractPosition;
use crate::tokens::token_amount_on_contract_token::DocumentActionTokenCost;
use platform_value::Identifier;
use std::collections::{BTreeMap, BTreeSet};

/// Trait providing getters for retrieving token costs associated with different document operations.
pub trait DocumentTypeV1Getters {
Expand Down Expand Up @@ -43,6 +46,15 @@ pub trait DocumentTypeV1Getters {
/// - `Some(TokenActionCost)` if a purchase cost exists.
/// - `None` if no cost is set for document purchase.
fn document_purchase_token_cost(&self) -> Option<DocumentActionTokenCost>;

/// Returns all document token costs. This is generally used only in internal validation.
fn all_document_token_costs(&self) -> Vec<&DocumentActionTokenCost>;

/// Returns the tokens used by external token costs as a set of token contract positions per contract.
/// This is generally used only in internal validation.
fn all_external_token_costs_contract_tokens(
&self,
) -> BTreeMap<Identifier, BTreeSet<TokenContractPosition>>;
}

/// Trait providing setters for assigning token costs to different document operations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ mod v0;
mod v1;

use crate::data_contract::config::DataContractConfig;
use crate::data_contract::document_type::v0::DocumentTypeV0;
use crate::data_contract::document_type::DocumentType;
use crate::data_contract::DocumentName;
use crate::data_contract::{DocumentName, TokenConfiguration, TokenContractPosition};
use crate::validation::operations::ProtocolValidationOperation;
use crate::version::PlatformVersion;
use crate::ProtocolError;
Expand Down Expand Up @@ -40,6 +39,7 @@ impl DocumentType {
data_contract_id: Identifier,
document_schemas: BTreeMap<DocumentName, Value>,
schema_defs: Option<&BTreeMap<String, Value>>,
token_configurations: &BTreeMap<TokenContractPosition, TokenConfiguration>,
data_contact_config: &DataContractConfig,
full_validation: bool,
has_tokens: bool,
Expand All @@ -53,20 +53,22 @@ impl DocumentType {
.class_method_versions
.create_document_types_from_document_schemas
{
0 => DocumentTypeV0::create_document_types_from_document_schemas_v0(
0 => DocumentType::create_document_types_from_document_schemas_v0(
data_contract_id,
document_schemas,
schema_defs,
token_configurations,
data_contact_config,
full_validation,
validation_operations,
platform_version,
),
// in v1 we add the ability to have contracts without documents and just tokens
1 => DocumentTypeV0::create_document_types_from_document_schemas_v1(
1 => DocumentType::create_document_types_from_document_schemas_v1(
data_contract_id,
document_schemas,
schema_defs,
token_configurations,
data_contact_config,
full_validation,
has_tokens,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
use crate::consensus::basic::data_contract::DocumentTypesAreMissingError;
use crate::data_contract::config::DataContractConfig;
use crate::data_contract::document_type::class_methods::consensus_or_protocol_data_contract_error;
use crate::data_contract::document_type::v0::DocumentTypeV0;
use crate::data_contract::document_type::DocumentType;
use crate::data_contract::DocumentName;
use crate::data_contract::{DocumentName, TokenConfiguration, TokenContractPosition};
use crate::validation::operations::ProtocolValidationOperation;
use crate::version::PlatformVersion;
use crate::ProtocolError;
use platform_value::{Identifier, Value};
use std::collections::BTreeMap;

impl DocumentTypeV0 {
impl DocumentType {
#[allow(clippy::too_many_arguments)]
pub(in crate::data_contract) fn create_document_types_from_document_schemas_v0(
data_contract_id: Identifier,
document_schemas: BTreeMap<DocumentName, Value>,
schema_defs: Option<&BTreeMap<String, Value>>,
token_configurations: &BTreeMap<TokenContractPosition, TokenConfiguration>,
data_contact_config: &DataContractConfig,
full_validation: bool,
validation_operations: &mut Vec<ProtocolValidationOperation>,
Expand All @@ -40,6 +41,7 @@ impl DocumentTypeV0 {
&name,
schema,
schema_defs,
token_configurations,
data_contact_config,
full_validation,
validation_operations,
Expand Down Expand Up @@ -84,6 +86,7 @@ mod tests {
id,
Default::default(),
None,
&BTreeMap::new(),
&config,
false,
false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use crate::consensus::basic::data_contract::DocumentTypesAreMissingError;
use crate::data_contract::config::DataContractConfig;
use crate::data_contract::document_type::class_methods::consensus_or_protocol_data_contract_error;
use crate::data_contract::document_type::v0::DocumentTypeV0;
use crate::data_contract::document_type::DocumentType;
use crate::data_contract::DocumentName;
use crate::data_contract::{DocumentName, TokenConfiguration, TokenContractPosition};
use crate::validation::operations::ProtocolValidationOperation;
use crate::version::PlatformVersion;
use crate::ProtocolError;
use platform_value::{Identifier, Value};
use std::collections::BTreeMap;

impl DocumentTypeV0 {
impl DocumentType {
#[allow(clippy::too_many_arguments)]
pub(in crate::data_contract) fn create_document_types_from_document_schemas_v1(
data_contract_id: Identifier,
document_schemas: BTreeMap<DocumentName, Value>,
schema_defs: Option<&BTreeMap<String, Value>>,
token_configurations: &BTreeMap<TokenContractPosition, TokenConfiguration>,
data_contact_config: &DataContractConfig,
full_validation: bool,
has_tokens: bool,
Expand All @@ -42,6 +42,7 @@ impl DocumentTypeV0 {
&name,
schema,
schema_defs,
token_configurations,
data_contact_config,
full_validation,
validation_operations,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::data_contract::document_type::{
property_names, DocumentProperty, DocumentPropertyType, DocumentType,
};
use crate::data_contract::errors::DataContractError;
use crate::data_contract::{TokenConfiguration, TokenContractPosition};
use crate::util::json_schema::resolve_uri;
use crate::validation::operations::ProtocolValidationOperation;
use crate::ProtocolError;
Expand Down Expand Up @@ -42,6 +43,7 @@ impl DocumentType {
name: &str,
schema: Value,
schema_defs: Option<&BTreeMap<String, Value>>,
token_configurations: &BTreeMap<TokenContractPosition, TokenConfiguration>,
data_contact_config: &DataContractConfig,
full_validation: bool,
validation_operations: &mut Vec<ProtocolValidationOperation>,
Expand Down Expand Up @@ -70,6 +72,7 @@ impl DocumentType {
name,
schema,
schema_defs,
token_configurations,
data_contact_config,
full_validation,
validation_operations,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@
use crate::consensus::basic::data_contract::ContestedUniqueIndexWithUniqueIndexError;
#[cfg(any(test, feature = "validation"))]
use crate::consensus::basic::data_contract::InvalidDocumentTypeNameError;
use crate::consensus::basic::data_contract::RedundantDocumentPaidForByTokenWithContractId;

Check warning on line 31 in packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs

View workflow job for this annotation

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

unused import: `crate::consensus::basic::data_contract::RedundantDocumentPaidForByTokenWithContractId`

warning: unused import: `crate::consensus::basic::data_contract::RedundantDocumentPaidForByTokenWithContractId` --> packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs:31:5 | 31 | use crate::consensus::basic::data_contract::RedundantDocumentPaidForByTokenWithContractId; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default
#[cfg(feature = "validation")]
use crate::consensus::basic::data_contract::TokenPaymentByBurningOnlyAllowedOnInternalTokenError;
#[cfg(feature = "validation")]
use crate::consensus::basic::document::MissingPositionsInDocumentTypePropertiesError;
use crate::consensus::basic::token::InvalidTokenPositionError;

Check warning on line 36 in packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs

View workflow job for this annotation

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

unused import: `crate::consensus::basic::token::InvalidTokenPositionError`

warning: unused import: `crate::consensus::basic::token::InvalidTokenPositionError` --> packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs:36:5 | 36 | use crate::consensus::basic::token::InvalidTokenPositionError; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#[cfg(feature = "validation")]
use crate::consensus::basic::BasicError;
use crate::data_contract::config::v0::DataContractConfigGettersV0;
Expand All @@ -56,7 +58,7 @@
use crate::data_contract::document_type::{property_names, DocumentType};
use crate::data_contract::errors::DataContractError;
use crate::data_contract::storage_requirements::keys_for_document_type::StorageKeyRequirements;
use crate::data_contract::TokenContractPosition;
use crate::data_contract::{TokenConfiguration, TokenContractPosition};
use crate::identity::SecurityLevel;
use crate::tokens::gas_fees_paid_by::GasFeesPaidBy;
use crate::tokens::token_amount_on_contract_token::{
Expand All @@ -78,6 +80,7 @@
name: &str,
schema: Value,
schema_defs: Option<&BTreeMap<String, Value>>,
token_configurations: &BTreeMap<TokenContractPosition, TokenConfiguration>,
data_contact_config: &DataContractConfig,
full_validation: bool, // we don't need to validate if loaded from state
validation_operations: &mut Vec<ProtocolValidationOperation>,
Expand Down Expand Up @@ -562,7 +565,7 @@
.transpose()?
.map(|action_cost| {
// Extract an optional contract_id. Adjust the key if necessary.
let contract_id = action_cost.get_optional_identifier("contractId")?;
let target_contract_id = action_cost.get_optional_identifier("contractId")?;
// Extract token_contract_position as an integer, then convert it.
let token_contract_position =
action_cost.get_integer::<TokenContractPosition>("tokenPosition")?;
Expand All @@ -577,15 +580,38 @@

#[cfg(feature = "validation")]
if full_validation {
// contract id is none if we are on our own contract
if target_contract_id.is_none() && !token_configurations.contains_key(&token_contract_position) {
return Err(ProtocolError::ConsensusError(
ConsensusError::BasicError(
BasicError::InvalidTokenPositionError(
InvalidTokenPositionError::new(
token_configurations.last_key_value().map(|(position, _)| *position),
token_contract_position,
),
),
)
.into(),
));
}

// If contractId is present and user tries to burn, bail out:
if let Some(contract_id) = contract_id {
if let Some(target_contract_id) = target_contract_id {
if target_contract_id == data_contract_id {
// we are in the same contract, but we set the data contract id
return Err(ProtocolError::ConsensusError(
ConsensusError::BasicError(
BasicError::RedundantDocumentPaidForByTokenWithContractId(RedundantDocumentPaidForByTokenWithContractId::new(target_contract_id))
)
.into(),
));
}
if effect == DocumentActionTokenEffect::BurnToken {
return Err(ProtocolError::ConsensusError(
ConsensusError::BasicError(
BasicError::TokenPaymentByBurningOnlyAllowedOnInternalTokenError(
TokenPaymentByBurningOnlyAllowedOnInternalTokenError::new(
contract_id,
target_contract_id,
token_contract_position,
key.to_string(),
),
Expand All @@ -605,7 +631,7 @@
.unwrap_or(GasFeesPaidBy::DocumentOwner);

Ok(DocumentActionTokenCost {
contract_id,
contract_id: target_contract_id,
token_contract_position,
token_amount,
effect,
Expand Down Expand Up @@ -686,6 +712,7 @@
"valid_name-a-b-123",
schema,
None,
&BTreeMap::new(),
&config,
true,
&mut vec![],
Expand Down Expand Up @@ -717,6 +744,7 @@
"",
schema,
None,
&BTreeMap::new(),
&config,
true,
&mut vec![],
Expand Down Expand Up @@ -759,6 +787,7 @@
&"a".repeat(65),
schema,
None,
&BTreeMap::new(),
&config,
true,
&mut vec![],
Expand Down Expand Up @@ -827,6 +856,7 @@
"invalid&name",
schema,
None,
&BTreeMap::new(),
&config,
true,
&mut vec![],
Expand Down
Loading
Loading