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