drive/state_transition_action/batch/
mod.rs1use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction;
2use crate::state_transition_action::batch::v0::BatchTransitionActionV0;
3use derive_more::From;
4use dpp::data_contract::accessors::v0::DataContractV0Getters;
5use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters;
6use crate::drive::contract_groups::types::ContractGroupMembershipsForContract;
7use dpp::fee::fee_result::FeeResult;
8use dpp::fee::Credits;
9use dpp::identity::SecurityLevel;
10use dpp::platform_value::Identifier;
11use dpp::prelude::UserFeeIncrease;
12use dpp::ProtocolError;
13use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0;
14
15pub mod batched_transition;
17pub mod v0;
19
20#[cfg(test)]
21mod tests;
22
23#[derive(Debug, Clone, Default)]
28pub struct ResolvedContractGroupMemberships {
29 pub memberships: ContractGroupMembershipsForContract,
31 pub fee: FeeResult,
33}
34
35#[derive(Debug, Clone, From)]
37pub enum BatchTransitionAction {
38 V0(BatchTransitionActionV0),
40}
41
42impl BatchTransitionAction {
43 pub fn owner_id(&self) -> Identifier {
45 match self {
46 BatchTransitionAction::V0(v0) => v0.owner_id,
47 }
48 }
49
50 pub fn transitions(&self) -> &Vec<BatchedTransitionAction> {
52 match self {
53 BatchTransitionAction::V0(v0) => &v0.transitions,
54 }
55 }
56
57 pub fn transitions_mut(&mut self) -> &mut Vec<BatchedTransitionAction> {
59 match self {
60 BatchTransitionAction::V0(v0) => &mut v0.transitions,
61 }
62 }
63
64 pub fn transitions_take(&mut self) -> Vec<BatchedTransitionAction> {
66 match self {
67 BatchTransitionAction::V0(v0) => std::mem::take(&mut v0.transitions),
68 }
69 }
70
71 pub fn transitions_owned(self) -> Vec<BatchedTransitionAction> {
73 match self {
74 BatchTransitionAction::V0(v0) => v0.transitions,
75 }
76 }
77
78 pub fn set_transitions(&mut self, transitions: Vec<BatchedTransitionAction>) {
80 match self {
81 BatchTransitionAction::V0(v0) => v0.transitions = transitions,
82 }
83 }
84
85 pub fn user_fee_increase(&self) -> UserFeeIncrease {
87 match self {
88 BatchTransitionAction::V0(transition) => transition.user_fee_increase,
89 }
90 }
91
92 pub fn contract_group_memberships(
94 &self,
95 contract_id: &Identifier,
96 ) -> Option<&ResolvedContractGroupMemberships> {
97 match self {
98 BatchTransitionAction::V0(v0) => v0.contract_group_memberships.get(contract_id),
99 }
100 }
101
102 pub fn set_contract_group_memberships(
104 &mut self,
105 contract_id: Identifier,
106 resolved: ResolvedContractGroupMemberships,
107 ) {
108 match self {
109 BatchTransitionAction::V0(v0) => {
110 v0.contract_group_memberships.insert(contract_id, resolved);
111 }
112 }
113 }
114}
115
116impl BatchTransitionAction {
117 pub fn all_used_balances(&self) -> Result<Option<Credits>, ProtocolError> {
119 match self {
120 BatchTransitionAction::V0(v0) => v0.all_used_balances(),
121 }
122 }
123
124 pub fn all_purchases_amount(&self) -> Result<Option<Credits>, ProtocolError> {
126 match self {
127 BatchTransitionAction::V0(v0) => v0.all_purchases_amount(),
128 }
129 }
130
131 pub fn all_conflicting_index_collateral_voting_funds(
133 &self,
134 ) -> Result<Option<Credits>, ProtocolError> {
135 match self {
136 BatchTransitionAction::V0(v0) => v0.all_conflicting_index_collateral_voting_funds(),
137 }
138 }
139
140 pub fn combined_security_level_requirement(&self) -> Result<Vec<SecurityLevel>, ProtocolError> {
167 let mut highest_security_level = SecurityLevel::lowest_level();
173
174 for transition in self.transitions().iter() {
175 match transition {
176 BatchedTransitionAction::DocumentAction(document_transition) => {
177 let document_type_name = document_transition.base().document_type_name();
178 let data_contract_info = document_transition.base().data_contract_fetch_info();
179
180 let document_type = data_contract_info
181 .contract
182 .document_type_for_name(document_type_name)?;
183
184 let document_security_level = document_type.security_level_requirement();
185
186 if document_security_level < highest_security_level {
188 highest_security_level = document_security_level
189 }
190 }
191 BatchedTransitionAction::TokenAction(_) => {
192 if highest_security_level != SecurityLevel::MASTER {
194 highest_security_level = SecurityLevel::CRITICAL
195 }
196 }
197 BatchedTransitionAction::BumpIdentityDataContractNonce(_) => {}
198 }
199 }
200 Ok(if highest_security_level == SecurityLevel::MASTER {
201 vec![SecurityLevel::MASTER]
202 } else {
203 (SecurityLevel::CRITICAL as u8..=highest_security_level as u8)
205 .map(|security_level| SecurityLevel::try_from(security_level).unwrap())
206 .collect()
207 })
208 }
209}