Skip to main content

drive/util/batch/drive_op_batch/
contract_moderation.rs

1use crate::drive::contract::moderation::types::ContractTeamActionWrite;
2use crate::drive::Drive;
3use crate::error::Error;
4use crate::fees::op::LowLevelDriveOperation;
5use crate::util::batch::drive_op_batch::DriveLowLevelOperationConverter;
6use dpp::block::block_info::BlockInfo;
7use dpp::data_contract::config::moderation::{
8    ContractDocumentRemoval, ContractModerationReason, ContractWarning,
9};
10use dpp::identifier::Identifier;
11use dpp::identity::TimestampMillis;
12use grovedb::batch::KeyInfoPath;
13use grovedb::{EstimatedLayerInformation, TransactionArg};
14use platform_version::version::PlatformVersion;
15use std::collections::HashMap;
16
17/// Operations on a moderated contract's banlist, suspension list, warning list, document
18/// removal records and, for an elected contract, its team's moderation action counts and the
19/// actions it votes on.
20#[derive(Clone, Debug)]
21pub enum ContractModerationOperationType {
22    /// Puts an identity on the banlist.
23    AddBan {
24        /// The moderated contract.
25        contract_id: Identifier,
26        /// The identity to ban.
27        identity_id: Identifier,
28        /// Why, stored with the entry.
29        reason: ContractModerationReason,
30        /// The identity that pays for the entry and receives its refund.
31        moderator_id: Identifier,
32    },
33    /// Takes an identity off the banlist.
34    RemoveBan {
35        /// The moderated contract.
36        contract_id: Identifier,
37        /// The identity to unban.
38        identity_id: Identifier,
39    },
40    /// Puts an identity on the suspension list until a block time, replacing an entry it
41    /// already has.
42    AddSuspension {
43        /// The moderated contract.
44        contract_id: Identifier,
45        /// The identity to suspend.
46        identity_id: Identifier,
47        /// The block time, in milliseconds, at which the suspension lapses.
48        until: TimestampMillis,
49        /// Why, stored with the entry.
50        reason: ContractModerationReason,
51        /// Whether the identity already has an entry, which is then replaced.
52        replaces_existing: bool,
53        /// The identity that pays for the entry and receives its refund.
54        moderator_id: Identifier,
55    },
56    /// Takes an identity off the suspension list, lapsed or not.
57    RemoveSuspension {
58        /// The moderated contract.
59        contract_id: Identifier,
60        /// The identity to unsuspend.
61        identity_id: Identifier,
62    },
63    /// Writes an identity's warning list entry with one warning more, replacing the entry it
64    /// already has.
65    AddWarning {
66        /// The moderated contract.
67        contract_id: Identifier,
68        /// The identity to warn.
69        identity_id: Identifier,
70        /// The identity's warnings after this one, oldest first: what the entry holds.
71        warnings: Vec<ContractWarning>,
72        /// Whether the identity already has an entry, which is then replaced.
73        replaces_existing: bool,
74        /// The identity that pays for the entry and receives its refund.
75        moderator_id: Identifier,
76    },
77    /// Takes an identity off the warning list: every warning it carries goes.
78    RemoveWarnings {
79        /// The moderated contract.
80        contract_id: Identifier,
81        /// The identity whose warnings are cleared.
82        identity_id: Identifier,
83    },
84    /// Writes the record of a moderator's deletion of a document: a fresh one, or the
85    /// replacement of the record the document already has. A record is replaced when a
86    /// moderator restores the document (the record then carries the restoration, the
87    /// deletion itself undone by a document operation of the same batch) and when a restored
88    /// document is deleted again (a fresh record, in place of the restored one). A document id
89    /// is produced at most once, so those are the only ways a record can exist already.
90    AddDocumentRemoval {
91        /// The moderated contract.
92        contract_id: Identifier,
93        /// The document type the document belonged to.
94        document_type_name: String,
95        /// The id the document had.
96        document_id: Identifier,
97        /// Whose it was, who removed it, why and when, what it was, and whether it was
98        /// restored since. Boxed: with the fields it keeps, it outweighs every other
99        /// operation of the kind.
100        removal: Box<ContractDocumentRemoval>,
101        /// The stored size of the record the document already has, which is then replaced;
102        /// `None` for a fresh record. An estimate prices a replacement by what it adds.
103        replaced_record_size: Option<u32>,
104        /// What the type's records are estimated to keep
105        /// (`types::estimated_document_removal_kept_fields_size`): the size the records a
106        /// write walks past are estimated at.
107        estimated_kept_fields_size: u32,
108        /// The identity that pays for the record, or for the bytes a replacement adds, and
109        /// receives its refund: the moderator that removed the document, or the one that
110        /// restored it.
111        moderator_id: Identifier,
112    },
113    /// Writes a seated moderation team member's proposal or approval of one of the contract's
114    /// team actions, closing the action when it meets its rule: see
115    /// `Drive::add_contract_team_action_signature_operations`.
116    AddTeamActionSignature {
117        /// The contract whose seated team votes on the action.
118        contract_id: Identifier,
119        /// The action.
120        action_id: Identifier,
121        /// The member that proposes or approves, who pays for what it adds.
122        signer_id: Identifier,
123        /// What the signature writes: a proposal, an approval, or the closing approval.
124        write: ContractTeamActionWrite,
125    },
126    /// Writes nothing: marks the batch it is in as one whose document operations' storage
127    /// removals refund nobody (`Drive::apply_drive_operations` generation 1, which applies them
128    /// as a GroveDB batch of their own when the batch also frees moderation storage someone is
129    /// owed). A
130    /// moderator's document deletion carries it, so whoever paid for the deleted document, its
131    /// owner or an earlier one, gets no storage refund, and nor does whoever created an index
132    /// subtree the deletion empties, unless the document's type refunds the owner
133    /// (`moderatorAbilities.deleteRefundsOwner`); the removal record the deletion replaces and
134    /// the team action approvals it moves refund as ever.
135    ForfeitStorageRefunds,
136    /// Writes a seated moderation team member's count of moderation actions on an elected
137    /// contract since the moderators pot was last settled.
138    SetActionCount {
139        /// The elected contract.
140        contract_id: Identifier,
141        /// The member that signed the action.
142        identity_id: Identifier,
143        /// The count to store, the action included.
144        count: u32,
145    },
146    /// Deletes moderation action counts of an elected contract: the reset of a settle of its
147    /// moderators pot. Each count must exist.
148    RemoveActionCounts {
149        /// The elected contract.
150        contract_id: Identifier,
151        /// The members whose counts go.
152        identity_ids: Vec<Identifier>,
153    },
154}
155
156impl DriveLowLevelOperationConverter for ContractModerationOperationType {
157    fn into_low_level_drive_operations(
158        self,
159        drive: &Drive,
160        estimated_costs_only_with_layer_info: &mut Option<
161            HashMap<KeyInfoPath, EstimatedLayerInformation>,
162        >,
163        block_info: &BlockInfo,
164        transaction: TransactionArg,
165        platform_version: &PlatformVersion,
166    ) -> Result<Vec<LowLevelDriveOperation>, Error> {
167        match self {
168            ContractModerationOperationType::AddBan {
169                contract_id,
170                identity_id,
171                reason,
172                moderator_id,
173            } => drive.add_contract_ban_operations(
174                contract_id,
175                identity_id,
176                &reason,
177                moderator_id,
178                block_info,
179                estimated_costs_only_with_layer_info,
180                transaction,
181                platform_version,
182            ),
183            ContractModerationOperationType::RemoveBan {
184                contract_id,
185                identity_id,
186            } => drive.remove_contract_ban_operations(
187                contract_id,
188                identity_id,
189                block_info,
190                estimated_costs_only_with_layer_info,
191                transaction,
192                platform_version,
193            ),
194            ContractModerationOperationType::AddSuspension {
195                contract_id,
196                identity_id,
197                until,
198                reason,
199                replaces_existing,
200                moderator_id,
201            } => drive.add_contract_suspension_operations(
202                contract_id,
203                identity_id,
204                until,
205                &reason,
206                replaces_existing,
207                moderator_id,
208                block_info,
209                estimated_costs_only_with_layer_info,
210                transaction,
211                platform_version,
212            ),
213            ContractModerationOperationType::RemoveSuspension {
214                contract_id,
215                identity_id,
216            } => drive.remove_contract_suspension_operations(
217                contract_id,
218                identity_id,
219                block_info,
220                estimated_costs_only_with_layer_info,
221                transaction,
222                platform_version,
223            ),
224            ContractModerationOperationType::AddWarning {
225                contract_id,
226                identity_id,
227                warnings,
228                replaces_existing,
229                moderator_id,
230            } => drive.add_contract_warning_operations(
231                contract_id,
232                identity_id,
233                &warnings,
234                replaces_existing,
235                moderator_id,
236                block_info,
237                estimated_costs_only_with_layer_info,
238                transaction,
239                platform_version,
240            ),
241            ContractModerationOperationType::RemoveWarnings {
242                contract_id,
243                identity_id,
244            } => drive.remove_contract_warnings_operations(
245                contract_id,
246                identity_id,
247                block_info,
248                estimated_costs_only_with_layer_info,
249                transaction,
250                platform_version,
251            ),
252            ContractModerationOperationType::AddDocumentRemoval {
253                contract_id,
254                document_type_name,
255                document_id,
256                removal,
257                replaced_record_size,
258                estimated_kept_fields_size,
259                moderator_id,
260            } => drive.add_contract_document_removal_operations(
261                contract_id,
262                &document_type_name,
263                document_id,
264                &removal,
265                replaced_record_size,
266                estimated_kept_fields_size,
267                moderator_id,
268                block_info,
269                estimated_costs_only_with_layer_info,
270                transaction,
271                platform_version,
272            ),
273            ContractModerationOperationType::AddTeamActionSignature {
274                contract_id,
275                action_id,
276                signer_id,
277                write,
278            } => drive.add_contract_team_action_signature_operations(
279                contract_id,
280                action_id,
281                signer_id,
282                &write,
283                block_info,
284                estimated_costs_only_with_layer_info,
285                transaction,
286                platform_version,
287            ),
288            ContractModerationOperationType::ForfeitStorageRefunds => Ok(vec![]),
289            ContractModerationOperationType::SetActionCount {
290                contract_id,
291                identity_id,
292                count,
293            } => drive.set_contract_moderation_action_count_operations(
294                contract_id,
295                identity_id,
296                count,
297                estimated_costs_only_with_layer_info,
298                platform_version,
299            ),
300            ContractModerationOperationType::RemoveActionCounts {
301                contract_id,
302                identity_ids,
303            } => drive.remove_contract_moderation_action_counts_operations(
304                contract_id,
305                &identity_ids,
306                estimated_costs_only_with_layer_info,
307                transaction,
308                platform_version,
309            ),
310        }
311    }
312}