drive/util/batch/drive_op_batch/
withdrawals.rs1use std::collections::HashMap;
2
3use crate::drive::identity::withdrawals::paths::{
4 get_withdrawal_root_path_vec, get_withdrawal_transactions_broadcasted_path_vec,
5 get_withdrawal_transactions_queue_path_vec, get_withdrawal_transactions_sum_tree_path_vec,
6 WITHDRAWAL_TRANSACTIONS_NEXT_INDEX_KEY,
7};
8use crate::util::grove_operations::{
9 BatchDeleteApplyType, BatchInsertApplyType, BatchMoveApplyType,
10};
11use crate::util::object_size_info::PathKeyElementInfo;
12use crate::{drive::Drive, error::Error, fees::op::LowLevelDriveOperation};
13use dpp::block::block_info::BlockInfo;
14
15use super::DriveLowLevelOperationConverter;
16use crate::query::Query;
17use dpp::fee::{Credits, SignedCredits};
18use dpp::prelude::TimestampMillis;
19use dpp::version::PlatformVersion;
20use dpp::withdrawal::{WithdrawalTransactionIndex, WithdrawalTransactionIndexAndBytes};
21use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, MaybeTree, TransactionArg};
22use grovedb::{Element, PathQuery, SizedQuery};
23
24#[derive(Clone, Debug)]
26pub enum WithdrawalOperationType {
27 UpdateIndexCounter {
29 index: WithdrawalTransactionIndex,
31 },
32 InsertTransactions {
34 withdrawal_transactions: Vec<WithdrawalTransactionIndexAndBytes>,
36 },
37 MoveWithdrawalTransactionsToBroadcasted {
39 indexes: Vec<WithdrawalTransactionIndex>,
41 },
42 MoveBroadcastedWithdrawalTransactionsBackToQueueForResigning {
44 indexes: Vec<WithdrawalTransactionIndex>,
46 },
47 DeleteCompletedBroadcastedWithdrawalTransactions {
49 indexes: Vec<WithdrawalTransactionIndex>,
51 },
52 ReserveWithdrawalAmount {
54 amount: Credits,
56 expiration_after: TimestampMillis,
58 },
59}
60
61impl DriveLowLevelOperationConverter for WithdrawalOperationType {
62 fn into_low_level_drive_operations(
63 self,
64 drive: &Drive,
65 _estimated_costs_only_with_layer_info: &mut Option<
66 HashMap<KeyInfoPath, EstimatedLayerInformation>,
67 >,
68 block_info: &BlockInfo,
69 transaction: TransactionArg,
70 platform_version: &PlatformVersion,
71 ) -> Result<Vec<LowLevelDriveOperation>, Error> {
72 match self {
73 WithdrawalOperationType::UpdateIndexCounter { index } => {
74 let mut drive_operations = vec![];
75
76 let path = get_withdrawal_root_path_vec();
77
78 drive.batch_insert(
79 PathKeyElementInfo::PathKeyRefElement::<'_, 1>((
80 path,
81 &WITHDRAWAL_TRANSACTIONS_NEXT_INDEX_KEY,
82 Element::Item(index.to_be_bytes().to_vec(), None),
83 )),
84 &mut drive_operations,
85 &platform_version.drive,
86 )?;
87
88 Ok(drive_operations)
89 }
90 WithdrawalOperationType::InsertTransactions {
91 withdrawal_transactions,
92 } => {
93 let mut drive_operations = vec![];
94
95 let path = get_withdrawal_transactions_queue_path_vec();
96
97 for (index, bytes) in withdrawal_transactions {
98 drive.batch_insert(
99 PathKeyElementInfo::PathKeyElement::<'_, 0>((
100 path.clone(),
101 index.to_be_bytes().to_vec(),
102 Element::Item(bytes, None),
103 )),
104 &mut drive_operations,
105 &platform_version.drive,
106 )?;
107 }
108
109 Ok(drive_operations)
110 }
111 WithdrawalOperationType::ReserveWithdrawalAmount {
112 amount,
113 expiration_after,
114 } => {
115 let mut drive_operations = vec![];
116
117 let expiration_date = block_info.time_ms + expiration_after;
118
119 let sum_path = get_withdrawal_transactions_sum_tree_path_vec();
120
121 drive.batch_insert_sum_item_or_add_to_if_already_exists(
122 PathKeyElementInfo::PathKeyElement::<'_, 0>((
123 sum_path.clone(),
124 expiration_date.to_be_bytes().to_vec(),
125 Element::SumItem(amount as SignedCredits, None),
126 )),
127 BatchInsertApplyType::StatefulBatchInsert,
128 transaction,
129 &mut drive_operations,
130 &platform_version.drive,
131 )?;
132
133 Ok(drive_operations)
134 }
135 WithdrawalOperationType::MoveWithdrawalTransactionsToBroadcasted { indexes } => {
136 let mut drive_operations = vec![];
137
138 if indexes.is_empty() {
139 return Ok(drive_operations);
140 }
141
142 let original_path = get_withdrawal_transactions_queue_path_vec();
143 let new_path = get_withdrawal_transactions_broadcasted_path_vec();
144
145 let mut query = Query::new();
146
147 let len = indexes.len();
148
149 query.insert_keys(
150 indexes
151 .into_iter()
152 .map(|index| index.to_be_bytes().to_vec())
153 .collect(),
154 );
155
156 let path_query = PathQuery::new(
157 original_path,
158 SizedQuery::new(query, Some(len as u16), None),
159 );
160
161 drive.batch_move_items_in_path_query(
162 &path_query,
163 new_path,
164 true,
165 BatchMoveApplyType::StatefulBatchMove {
167 is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree),
168 },
169 None,
170 transaction,
171 &mut drive_operations,
172 &platform_version.drive,
173 )?;
174
175 Ok(drive_operations)
176 }
177 WithdrawalOperationType::MoveBroadcastedWithdrawalTransactionsBackToQueueForResigning { indexes } => {
178 let mut drive_operations = vec![];
179
180 if indexes.is_empty() {
181 return Ok(drive_operations);
182 }
183
184 let original_path = get_withdrawal_transactions_broadcasted_path_vec();
185 let new_path = get_withdrawal_transactions_queue_path_vec();
186
187 let mut query = Query::new();
188
189 let len = indexes.len();
190
191 query.insert_keys(
192 indexes
193 .into_iter()
194 .map(|index| index.to_be_bytes().to_vec())
195 .collect(),
196 );
197
198 let path_query = PathQuery::new(
199 original_path,
200 SizedQuery::new(query, Some(len as u16), None),
201 );
202
203 drive.batch_move_items_in_path_query(
204 &path_query,
205 new_path,
206 true,
207 BatchMoveApplyType::StatefulBatchMove {
209 is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree),
210 },
211 None,
212 transaction,
213 &mut drive_operations,
214 &platform_version.drive,
215 )?;
216
217 Ok(drive_operations)
218 }
219 WithdrawalOperationType::DeleteCompletedBroadcastedWithdrawalTransactions { indexes } => {
220 let mut drive_operations = vec![];
221
222 if indexes.is_empty() {
223 return Ok(drive_operations);
224 }
225
226 let path = get_withdrawal_transactions_broadcasted_path_vec();
227
228 let mut query = Query::new();
229
230 let len = indexes.len();
231
232 query.insert_keys(
233 indexes
234 .into_iter()
235 .map(|index| index.to_be_bytes().to_vec())
236 .collect(),
237 );
238
239 let path_query = PathQuery::new(
240 path,
241 SizedQuery::new(query, Some(len as u16), None),
242 );
243
244 drive.batch_delete_items_in_path_query(
245 &path_query,
246 true,
247 BatchDeleteApplyType::StatefulBatchDelete {
249 is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree),
250 },
251 transaction,
252 &mut drive_operations,
253 &platform_version.drive,
254 )?;
255
256 Ok(drive_operations)
257 }
258 }
259 }
260}