dpp/state_transition/traits/state_transition_estimated_fee_validation.rs
1use crate::address_funds::PlatformAddress;
2use crate::consensus::state::address_funds::AddressesNotEnoughFundsError;
3use crate::fee::Credits;
4use crate::prelude::AddressNonce;
5use crate::validation::{ConsensusValidationResult, SimpleConsensusValidationResult};
6use crate::ProtocolError;
7use platform_version::version::PlatformVersion;
8use std::collections::BTreeMap;
9
10/// Trait for estimating fees for state transitions.
11///
12/// This trait provides a method to calculate estimated fees based on the
13/// transition's characteristics (inputs, outputs, etc.).
14pub trait StateTransitionEstimatedFeeValidation {
15 /// Calculates the estimated minimum fee required for this state transition.
16 ///
17 /// The fee is calculated based on the number of inputs, outputs, and any
18 /// transition-specific costs (e.g., key creation costs for identity creation).
19 ///
20 /// # Arguments
21 ///
22 /// * `platform_version` - The platform version containing fee configuration.
23 ///
24 /// # Returns
25 ///
26 /// The estimated fee in credits.
27 fn calculate_min_required_fee(
28 &self,
29 platform_version: &PlatformVersion,
30 ) -> Result<Credits, ProtocolError>;
31}
32
33/// Trait for validating that address-based state transitions have sufficient funds for fees.
34///
35/// This trait extends fee estimation with validation capabilities specific to
36/// address-based state transitions that pay fees from address balances rather
37/// than identity balances.
38pub trait StateTransitionAddressEstimatedFeeValidation:
39 StateTransitionEstimatedFeeValidation
40{
41 /// Validates that sufficient funds are available to cover the estimated fee.
42 ///
43 /// This is a pre-check validation to quickly verify that the addresses
44 /// referenced in the fee strategy have enough remaining balance to pay
45 /// the estimated fee.
46 ///
47 /// # Arguments
48 ///
49 /// * `remaining_balances` - The remaining balances of addresses after input amounts are consumed.
50 /// * `platform_version` - The platform version containing fee configuration.
51 ///
52 /// # Returns
53 ///
54 /// A validation result. If validation fails, contains an `AddressesNotEnoughFundsError`.
55 fn validate_estimated_fee(
56 &self,
57 remaining_balances: &BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
58 platform_version: &PlatformVersion,
59 ) -> Result<ConsensusValidationResult<Credits>, ProtocolError> {
60 let required_fee = self.calculate_min_required_fee(platform_version)?;
61 let amount_available = self.calculate_amount_available(remaining_balances);
62
63 Ok(if amount_available < required_fee {
64 ConsensusValidationResult::new_with_error(
65 AddressesNotEnoughFundsError::new(remaining_balances.clone(), required_fee).into(),
66 )
67 } else {
68 ConsensusValidationResult::new()
69 })
70 }
71
72 /// Calculates the total amount available for fee payment based on the fee strategy.
73 ///
74 /// This examines the transition's fee strategy and sums up the available credits
75 /// from inputs (via `DeductFromInput`) and outputs (via `ReduceOutput`) that are
76 /// designated for fee payment.
77 ///
78 /// # Arguments
79 ///
80 /// * `remaining_balances` - The remaining balances of addresses after input amounts are consumed.
81 ///
82 /// # Returns
83 ///
84 /// The total credits available for fee payment.
85 fn calculate_amount_available(
86 &self,
87 remaining_balances: &BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
88 ) -> Credits;
89}
90
91/// Trait for validating that identity-based state transitions have sufficient funds for fees.
92///
93/// This trait extends fee estimation with validation capabilities specific to
94/// identity-based state transitions that pay fees from identity balances.
95pub trait StateTransitionIdentityEstimatedFeeValidation:
96 StateTransitionEstimatedFeeValidation
97{
98 /// Validates that sufficient identity balance is available to cover the estimated fee.
99 ///
100 /// # Arguments
101 ///
102 /// * `identity_known_balance` - The known balance of the identity.
103 /// * `platform_version` - The platform version containing fee configuration.
104 ///
105 /// # Returns
106 ///
107 /// A validation result. If validation fails, contains an `IdentityInsufficientBalanceError`.
108 fn validate_estimated_fee(
109 &self,
110 identity_known_balance: Credits,
111 platform_version: &PlatformVersion,
112 ) -> Result<SimpleConsensusValidationResult, ProtocolError>;
113}