drive/util/batch/drive_op_batch/
identity.rs

1use crate::drive::Drive;
2use crate::error::Error;
3use crate::fees::op::LowLevelDriveOperation;
4use crate::util::batch::drive_op_batch::DriveLowLevelOperationConverter;
5use dpp::block::block_info::BlockInfo;
6use dpp::identity::{Identity, IdentityPublicKey, KeyID};
7use dpp::prelude::{IdentityNonce, Revision};
8
9use crate::drive::identity::update::methods::merge_identity_nonce::MergeIdentityContractNonceResultToResult;
10use crate::drive::votes::resolved::votes::ResolvedVote;
11use crate::state_transition_action::identity::masternode_vote::v0::PreviousVoteCount;
12use dpp::version::PlatformVersion;
13use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice;
14use grovedb::batch::KeyInfoPath;
15use grovedb::{EstimatedLayerInformation, TransactionArg};
16use std::collections::HashMap;
17
18/// Operations on Identities
19#[allow(clippy::large_enum_variant)]
20#[derive(Clone, Debug)]
21pub enum IdentityOperationType {
22    /// Inserts a new identity to the `Identities` subtree.
23    /// A masternode identity is an identity, but can not have unique keys.
24    /// It also will skip testing for unique keys when adding non unique keys, so no one will
25    /// take a key, then add it to a masternode
26    AddNewIdentity {
27        /// The identity we wish to insert
28        identity: Identity,
29        /// Is this identity a masternode identity
30        /// On Masternode identities we do not add lookup key hashes
31        is_masternode_identity: bool,
32    },
33    /// Adds balance to an identity
34    AddToIdentityBalance {
35        /// The identity id of the identity
36        identity_id: [u8; 32],
37        /// The added balance
38        added_balance: u64,
39    },
40    /// Removes balance from an identity
41    RemoveFromIdentityBalance {
42        /// The identity id of the identity
43        identity_id: [u8; 32],
44        /// The balance that will be removed from the identity
45        /// This needs to be verified in advance
46        balance_to_remove: u64,
47    },
48    /// Adds an array of keys to the identity
49    AddNewKeysToIdentity {
50        /// The identity id of the identity
51        identity_id: [u8; 32],
52        /// The unique keys to be added
53        unique_keys_to_add: Vec<IdentityPublicKey>,
54        /// The non unique keys to be added
55        non_unique_keys_to_add: Vec<IdentityPublicKey>,
56    },
57    /// Disable Identity Keys
58    DisableIdentityKeys {
59        /// The identity id of the identity
60        identity_id: [u8; 32],
61        /// The keys to be added
62        keys_ids: Vec<KeyID>,
63    },
64
65    /// Re-Enable Identity Keys
66    /// This should only be used internally in Drive (for masternode identities)
67    ReEnableIdentityKeys {
68        /// The identity id of the identity
69        identity_id: [u8; 32],
70        /// The keys to be added
71        keys_ids: Vec<KeyID>,
72    },
73
74    /// Updates an identities revision.
75    UpdateIdentityRevision {
76        /// The revision id
77        identity_id: [u8; 32],
78        /// The revision we are updating to
79        revision: Revision,
80    },
81    /// Casts a votes as a masternode.
82    MasternodeCastVote {
83        /// The pro tx hash of the masternode doing the voting
84        voter_pro_tx_hash: [u8; 32],
85        /// The strength of the vote, masternodes have 1, evonodes have 4,
86        strength: u8,
87        /// Contested Vote type
88        vote: ResolvedVote,
89        /// Remove previous contested resource vote choice
90        previous_resource_vote_choice_to_remove: Option<(ResourceVoteChoice, PreviousVoteCount)>,
91    },
92    /// Updates an identities nonce for a specific contract.
93    UpdateIdentityNonce {
94        /// The revision id
95        identity_id: [u8; 32],
96        /// The nonce we are updating to
97        nonce: IdentityNonce,
98    },
99
100    /// Updates an identities nonce for a specific contract.
101    UpdateIdentityContractNonce {
102        /// The revision id
103        identity_id: [u8; 32],
104        /// The contract id
105        contract_id: [u8; 32],
106        /// The nonce we are updating to
107        nonce: IdentityNonce,
108    },
109}
110
111impl DriveLowLevelOperationConverter for IdentityOperationType {
112    fn into_low_level_drive_operations(
113        self,
114        drive: &Drive,
115        estimated_costs_only_with_layer_info: &mut Option<
116            HashMap<KeyInfoPath, EstimatedLayerInformation>,
117        >,
118        block_info: &BlockInfo,
119        transaction: TransactionArg,
120        platform_version: &PlatformVersion,
121    ) -> Result<Vec<LowLevelDriveOperation>, Error> {
122        match self {
123            IdentityOperationType::AddNewIdentity {
124                identity,
125                is_masternode_identity,
126            } => drive.add_new_identity_operations(
127                identity,
128                is_masternode_identity,
129                block_info,
130                &mut None,
131                estimated_costs_only_with_layer_info,
132                transaction,
133                platform_version,
134            ),
135            IdentityOperationType::AddToIdentityBalance {
136                identity_id,
137                added_balance,
138            } => drive.add_to_identity_balance_operations(
139                identity_id,
140                added_balance,
141                estimated_costs_only_with_layer_info,
142                transaction,
143                platform_version,
144            ),
145            IdentityOperationType::RemoveFromIdentityBalance {
146                identity_id,
147                balance_to_remove,
148            } => drive.remove_from_identity_balance_operations(
149                identity_id,
150                balance_to_remove,
151                estimated_costs_only_with_layer_info,
152                transaction,
153                platform_version,
154            ),
155            IdentityOperationType::AddNewKeysToIdentity {
156                identity_id,
157                unique_keys_to_add,
158                non_unique_keys_to_add,
159            } => drive.add_new_keys_to_identity_operations(
160                identity_id,
161                unique_keys_to_add,
162                non_unique_keys_to_add,
163                true,
164                &block_info.epoch,
165                estimated_costs_only_with_layer_info,
166                transaction,
167                platform_version,
168            ),
169            IdentityOperationType::DisableIdentityKeys {
170                identity_id,
171                keys_ids,
172            } => drive.disable_identity_keys_operations(
173                identity_id,
174                keys_ids,
175                block_info.time_ms,
176                &block_info.epoch,
177                estimated_costs_only_with_layer_info,
178                transaction,
179                platform_version,
180            ),
181            IdentityOperationType::ReEnableIdentityKeys {
182                identity_id,
183                keys_ids,
184            } => drive.re_enable_identity_keys_operations(
185                identity_id,
186                keys_ids,
187                &block_info.epoch,
188                estimated_costs_only_with_layer_info,
189                transaction,
190                platform_version,
191            ),
192            IdentityOperationType::UpdateIdentityRevision {
193                identity_id,
194                revision,
195            } => Ok(vec![drive.update_identity_revision_operation(
196                identity_id,
197                revision,
198                estimated_costs_only_with_layer_info,
199                platform_version,
200            )?]),
201            IdentityOperationType::MasternodeCastVote {
202                voter_pro_tx_hash,
203                strength,
204                vote,
205                previous_resource_vote_choice_to_remove,
206            } => {
207                // No need to have estimated_costs_only_with_layer_info and block_info here
208                // This is because voting is a special operation with a fixed cost
209                drive.register_identity_vote_operations(
210                    voter_pro_tx_hash,
211                    strength,
212                    vote,
213                    previous_resource_vote_choice_to_remove,
214                    transaction,
215                    platform_version,
216                )
217            }
218            IdentityOperationType::UpdateIdentityContractNonce {
219                identity_id,
220                contract_id,
221                nonce,
222            } => {
223                let (result, operations) = drive.merge_identity_contract_nonce_operations(
224                    identity_id,
225                    contract_id,
226                    nonce,
227                    block_info,
228                    estimated_costs_only_with_layer_info,
229                    transaction,
230                    platform_version,
231                )?;
232                result.to_result()?;
233                Ok(operations)
234            }
235            IdentityOperationType::UpdateIdentityNonce { identity_id, nonce } => {
236                let (result, operations) = drive.merge_identity_nonce_operations(
237                    identity_id,
238                    nonce,
239                    block_info,
240                    estimated_costs_only_with_layer_info,
241                    transaction,
242                    platform_version,
243                )?;
244                result.to_result()?;
245                Ok(operations)
246            }
247        }
248    }
249}