drive/state_transition_action/shielded/shielded_withdrawal/
mod.rs1pub mod transformer;
3pub mod v0;
5
6use crate::state_transition_action::shielded::shielded_withdrawal::v0::ShieldedWithdrawalTransitionActionV0;
7use crate::state_transition_action::shielded::ShieldedActionNote;
8use derive_more::From;
9use dpp::document::Document;
10use dpp::fee::Credits;
11use dpp::identity::core_script::CoreScript;
12use dpp::withdrawal::Pooling;
13
14#[derive(Debug, Clone, From)]
16pub enum ShieldedWithdrawalTransitionAction {
17 V0(ShieldedWithdrawalTransitionActionV0),
19}
20
21impl ShieldedWithdrawalTransitionAction {
22 pub fn amount(&self) -> Credits {
24 match self {
25 ShieldedWithdrawalTransitionAction::V0(transition) => transition.amount,
26 }
27 }
28 pub fn notes(&self) -> &[ShieldedActionNote] {
30 match self {
31 ShieldedWithdrawalTransitionAction::V0(transition) => &transition.notes,
32 }
33 }
34 pub fn anchor(&self) -> &[u8; 32] {
36 match self {
37 ShieldedWithdrawalTransitionAction::V0(transition) => &transition.anchor,
38 }
39 }
40 pub fn core_fee_per_byte(&self) -> u32 {
42 match self {
43 ShieldedWithdrawalTransitionAction::V0(transition) => transition.core_fee_per_byte,
44 }
45 }
46 pub fn pooling(&self) -> Pooling {
48 match self {
49 ShieldedWithdrawalTransitionAction::V0(transition) => transition.pooling,
50 }
51 }
52 pub fn output_script(&self) -> &CoreScript {
54 match self {
55 ShieldedWithdrawalTransitionAction::V0(transition) => &transition.output_script,
56 }
57 }
58 pub fn fee_amount(&self) -> Credits {
60 match self {
61 ShieldedWithdrawalTransitionAction::V0(transition) => transition.fee_amount,
62 }
63 }
64 pub fn prepared_withdrawal_document(&self) -> &Document {
66 match self {
67 ShieldedWithdrawalTransitionAction::V0(transition) => {
68 &transition.prepared_withdrawal_document
69 }
70 }
71 }
72 pub fn prepared_withdrawal_document_owned(self) -> Document {
74 match self {
75 ShieldedWithdrawalTransitionAction::V0(transition) => {
76 transition.prepared_withdrawal_document
77 }
78 }
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use dpp::document::DocumentV0;
86 use dpp::prelude::Identifier;
87
88 fn make_note() -> ShieldedActionNote {
89 ShieldedActionNote {
90 nullifier: [0x77; 32],
91 cmx: [0x88; 32],
92 cv_net: [0x22; 32],
93 encrypted_note: vec![0xFE, 0xED],
94 }
95 }
96
97 fn make_document() -> Document {
98 Document::V0(DocumentV0 {
99 contract_version: None,
100 id: Identifier::from([0x11; 32]),
101 owner_id: Identifier::from([0x22; 32]),
102 properties: Default::default(),
103 revision: Some(1),
104 created_at: None,
105 updated_at: None,
106 transferred_at: None,
107 created_at_block_height: None,
108 updated_at_block_height: None,
109 transferred_at_block_height: None,
110 created_at_core_block_height: None,
111 updated_at_core_block_height: None,
112 transferred_at_core_block_height: None,
113 creator_id: None,
114 moderated_at: None,
115 moderated_by: None,
116 })
117 }
118
119 fn make_action() -> ShieldedWithdrawalTransitionAction {
120 let v0 = ShieldedWithdrawalTransitionActionV0 {
121 amount: 25000,
122 notes: vec![make_note(), make_note()],
123 anchor: [0x99; 32],
124 core_fee_per_byte: 42,
125 pooling: Pooling::Never,
126 output_script: CoreScript::from_bytes(vec![0x76, 0xA9, 0x14]),
127 fee_amount: 500,
128 current_total_balance: 300000,
129 prepared_withdrawal_document: make_document(),
130 };
131 ShieldedWithdrawalTransitionAction::from(v0)
132 }
133
134 #[test]
135 fn test_from_v0() {
136 let action = make_action();
137 assert!(matches!(action, ShieldedWithdrawalTransitionAction::V0(_)));
138 }
139
140 #[test]
141 fn test_amount() {
142 let action = make_action();
143 assert_eq!(action.amount(), 25000);
144 }
145
146 #[test]
147 fn test_notes() {
148 let action = make_action();
149 let notes = action.notes();
150 assert_eq!(notes.len(), 2);
151 assert_eq!(notes[0].nullifier, [0x77; 32]);
152 assert_eq!(notes[1].cmx, [0x88; 32]);
153 }
154
155 #[test]
156 fn test_anchor() {
157 let action = make_action();
158 assert_eq!(*action.anchor(), [0x99; 32]);
159 }
160
161 #[test]
162 fn test_core_fee_per_byte() {
163 let action = make_action();
164 assert_eq!(action.core_fee_per_byte(), 42);
165 }
166
167 #[test]
168 fn test_pooling() {
169 let action = make_action();
170 assert!(matches!(action.pooling(), Pooling::Never));
171 }
172
173 #[test]
174 fn test_pooling_variants() {
175 let mut v0 = ShieldedWithdrawalTransitionActionV0 {
176 amount: 0,
177 notes: vec![],
178 anchor: [0; 32],
179 core_fee_per_byte: 0,
180 pooling: Pooling::IfAvailable,
181 output_script: CoreScript::from_bytes(vec![]),
182 fee_amount: 0,
183 current_total_balance: 0,
184 prepared_withdrawal_document: make_document(),
185 };
186 let action_if_avail = ShieldedWithdrawalTransitionAction::from(v0.clone());
187 assert!(matches!(action_if_avail.pooling(), Pooling::IfAvailable));
188
189 v0.pooling = Pooling::Standard;
190 let action_standard = ShieldedWithdrawalTransitionAction::from(v0);
191 assert!(matches!(action_standard.pooling(), Pooling::Standard));
192 }
193
194 #[test]
195 fn test_output_script() {
196 let action = make_action();
197 let script = action.output_script();
198 assert_eq!(script.as_bytes(), &[0x76, 0xA9, 0x14]);
199 }
200
201 #[test]
202 fn test_fee_amount() {
203 let action = make_action();
204 assert_eq!(action.fee_amount(), 500);
205 }
206
207 #[test]
208 fn test_prepared_withdrawal_document_ref() {
209 let action = make_action();
210 let doc = action.prepared_withdrawal_document();
211 match doc {
212 Document::V0(v0) => {
213 assert_eq!(v0.id, Identifier::from([0x11; 32]));
214 assert_eq!(v0.owner_id, Identifier::from([0x22; 32]));
215 }
216 }
217 }
218
219 #[test]
220 fn test_prepared_withdrawal_document_owned() {
221 let action = make_action();
222 let doc = action.prepared_withdrawal_document_owned();
223 match doc {
224 Document::V0(v0) => {
225 assert_eq!(v0.id, Identifier::from([0x11; 32]));
226 }
227 }
228 }
229
230 #[test]
231 fn test_clone() {
232 let action = make_action();
233 let cloned = action.clone();
234 assert_eq!(cloned.amount(), 25000);
235 assert_eq!(cloned.fee_amount(), 500);
236 assert_eq!(cloned.core_fee_per_byte(), 42);
237 assert_eq!(cloned.notes().len(), 2);
238 }
239
240 #[test]
241 fn test_debug() {
242 let action = make_action();
243 let debug_str = format!("{:?}", action);
244 assert!(debug_str.contains("V0"));
245 }
246}