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