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 id: Identifier::from([0x11; 32]),
100 owner_id: Identifier::from([0x22; 32]),
101 properties: Default::default(),
102 revision: Some(1),
103 created_at: None,
104 updated_at: None,
105 transferred_at: None,
106 created_at_block_height: None,
107 updated_at_block_height: None,
108 transferred_at_block_height: None,
109 created_at_core_block_height: None,
110 updated_at_core_block_height: None,
111 transferred_at_core_block_height: None,
112 creator_id: None,
113 })
114 }
115
116 fn make_action() -> ShieldedWithdrawalTransitionAction {
117 let v0 = ShieldedWithdrawalTransitionActionV0 {
118 amount: 25000,
119 notes: vec![make_note(), make_note()],
120 anchor: [0x99; 32],
121 core_fee_per_byte: 42,
122 pooling: Pooling::Never,
123 output_script: CoreScript::from_bytes(vec![0x76, 0xA9, 0x14]),
124 fee_amount: 500,
125 current_total_balance: 300000,
126 prepared_withdrawal_document: make_document(),
127 };
128 ShieldedWithdrawalTransitionAction::from(v0)
129 }
130
131 #[test]
132 fn test_from_v0() {
133 let action = make_action();
134 assert!(matches!(action, ShieldedWithdrawalTransitionAction::V0(_)));
135 }
136
137 #[test]
138 fn test_amount() {
139 let action = make_action();
140 assert_eq!(action.amount(), 25000);
141 }
142
143 #[test]
144 fn test_notes() {
145 let action = make_action();
146 let notes = action.notes();
147 assert_eq!(notes.len(), 2);
148 assert_eq!(notes[0].nullifier, [0x77; 32]);
149 assert_eq!(notes[1].cmx, [0x88; 32]);
150 }
151
152 #[test]
153 fn test_anchor() {
154 let action = make_action();
155 assert_eq!(*action.anchor(), [0x99; 32]);
156 }
157
158 #[test]
159 fn test_core_fee_per_byte() {
160 let action = make_action();
161 assert_eq!(action.core_fee_per_byte(), 42);
162 }
163
164 #[test]
165 fn test_pooling() {
166 let action = make_action();
167 assert!(matches!(action.pooling(), Pooling::Never));
168 }
169
170 #[test]
171 fn test_pooling_variants() {
172 let mut v0 = ShieldedWithdrawalTransitionActionV0 {
173 amount: 0,
174 notes: vec![],
175 anchor: [0; 32],
176 core_fee_per_byte: 0,
177 pooling: Pooling::IfAvailable,
178 output_script: CoreScript::from_bytes(vec![]),
179 fee_amount: 0,
180 current_total_balance: 0,
181 prepared_withdrawal_document: make_document(),
182 };
183 let action_if_avail = ShieldedWithdrawalTransitionAction::from(v0.clone());
184 assert!(matches!(action_if_avail.pooling(), Pooling::IfAvailable));
185
186 v0.pooling = Pooling::Standard;
187 let action_standard = ShieldedWithdrawalTransitionAction::from(v0);
188 assert!(matches!(action_standard.pooling(), Pooling::Standard));
189 }
190
191 #[test]
192 fn test_output_script() {
193 let action = make_action();
194 let script = action.output_script();
195 assert_eq!(script.as_bytes(), &[0x76, 0xA9, 0x14]);
196 }
197
198 #[test]
199 fn test_fee_amount() {
200 let action = make_action();
201 assert_eq!(action.fee_amount(), 500);
202 }
203
204 #[test]
205 fn test_prepared_withdrawal_document_ref() {
206 let action = make_action();
207 let doc = action.prepared_withdrawal_document();
208 match doc {
209 Document::V0(v0) => {
210 assert_eq!(v0.id, Identifier::from([0x11; 32]));
211 assert_eq!(v0.owner_id, Identifier::from([0x22; 32]));
212 }
213 }
214 }
215
216 #[test]
217 fn test_prepared_withdrawal_document_owned() {
218 let action = make_action();
219 let doc = action.prepared_withdrawal_document_owned();
220 match doc {
221 Document::V0(v0) => {
222 assert_eq!(v0.id, Identifier::from([0x11; 32]));
223 }
224 }
225 }
226
227 #[test]
228 fn test_clone() {
229 let action = make_action();
230 let cloned = action.clone();
231 assert_eq!(cloned.amount(), 25000);
232 assert_eq!(cloned.fee_amount(), 500);
233 assert_eq!(cloned.core_fee_per_byte(), 42);
234 assert_eq!(cloned.notes().len(), 2);
235 }
236
237 #[test]
238 fn test_debug() {
239 let action = make_action();
240 let debug_str = format!("{:?}", action);
241 assert!(debug_str.contains("V0"));
242 }
243}