drive/state_transition_action/batch/v0/
mod.rs

1use dpp::fee::Credits;
2use crate::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction;
3use dpp::identifier::Identifier;
4use dpp::prelude::UserFeeIncrease;
5use dpp::ProtocolError;
6use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction;
7use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0;
8use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0;
9use crate::state_transition_action::batch::batched_transition::token_transition::token_direct_purchase_transition_action::TokenDirectPurchaseTransitionActionAccessorsV0;
10use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction;
11
12/// action v0
13#[derive(Default, Debug, Clone)]
14pub struct BatchTransitionActionV0 {
15    /// The owner making the transitions
16    pub owner_id: Identifier,
17    /// The inner transitions
18    pub transitions: Vec<BatchedTransitionAction>,
19    /// fee multiplier
20    pub user_fee_increase: UserFeeIncrease,
21}
22
23impl BatchTransitionActionV0 {
24    pub(in crate::state_transition_action) fn all_used_balances(
25        &self,
26    ) -> Result<Option<Credits>, ProtocolError> {
27        Ok(match (self.all_purchases_amount()?, self.all_conflicting_index_collateral_voting_funds()?) {
28            (Some(all_purchases_amount), Some(all_conflicting_index_collateral_voting_funds)) => Some(all_purchases_amount.checked_add(all_conflicting_index_collateral_voting_funds).ok_or(ProtocolError::Overflow("overflow between all_purchases_amount and all_conflicting_index_collateral_voting_funds"))?),
29            (Some(all_purchases_amount), None) => Some(all_purchases_amount),
30            (None, Some(all_conflicting_index_collateral_voting_funds)) => Some(all_conflicting_index_collateral_voting_funds),
31            (None, None) => None,
32        })
33    }
34    pub(in crate::state_transition_action) fn all_purchases_amount(
35        &self,
36    ) -> Result<Option<Credits>, ProtocolError> {
37        let (total, any_purchases): (Option<Credits>, bool) = self
38            .transitions
39            .iter()
40            .filter_map(|transition| match transition {
41                BatchedTransitionAction::DocumentAction(
42                    DocumentTransitionAction::PurchaseAction(document_purchase),
43                ) => Some(document_purchase.price()),
44                BatchedTransitionAction::TokenAction(
45                    TokenTransitionAction::DirectPurchaseAction(token_purchase),
46                ) => Some(token_purchase.total_agreed_price()),
47                _ => None,
48            })
49            .fold((None, false), |(acc, _), price| match acc {
50                Some(acc_val) => acc_val
51                    .checked_add(price)
52                    .map_or((None, true), |sum| (Some(sum), true)),
53                None => (Some(price), true),
54            });
55
56        match (total, any_purchases) {
57            (Some(total), _) => Ok(Some(total)),
58            (None, true) => Err(ProtocolError::Overflow("overflow in all purchases amount")), // Overflow occurred
59            _ => Ok(None), // No purchases were found
60        }
61    }
62
63    pub(in crate::state_transition_action) fn all_conflicting_index_collateral_voting_funds(
64        &self,
65    ) -> Result<Option<Credits>, ProtocolError> {
66        let (total, any_voting_funds): (Option<Credits>, bool) = self
67            .transitions
68            .iter()
69            .filter_map(|transition| match transition {
70                BatchedTransitionAction::DocumentAction(
71                    DocumentTransitionAction::CreateAction(document_create_transition_action),
72                ) => document_create_transition_action
73                    .prefunded_voting_balance()
74                    .iter()
75                    .try_fold(0u64, |acc, &(_, val)| acc.checked_add(val)),
76                _ => None,
77            })
78            .fold((None, false), |(acc, _), price| match acc {
79                Some(acc_val) => acc_val
80                    .checked_add(price)
81                    .map_or((None, true), |sum| (Some(sum), true)),
82                None => (Some(price), true),
83            });
84
85        match (total, any_voting_funds) {
86            (Some(total), _) => Ok(Some(total)),
87            (None, true) => Err(ProtocolError::Overflow(
88                "overflow in all voting funds amount",
89            )), // Overflow occurred
90            _ => Ok(None),
91        }
92    }
93}