Skip to main content

drive/state_transition_action/shielded/shielded_withdrawal/
mod.rs

1/// transformer
2pub mod transformer;
3/// v0
4pub 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/// Shielded withdrawal transition action
15#[derive(Debug, Clone, From)]
16pub enum ShieldedWithdrawalTransitionAction {
17    /// v0
18    V0(ShieldedWithdrawalTransitionActionV0),
19}
20
21impl ShieldedWithdrawalTransitionAction {
22    /// Get withdrawal amount
23    pub fn amount(&self) -> Credits {
24        match self {
25            ShieldedWithdrawalTransitionAction::V0(transition) => transition.amount,
26        }
27    }
28    /// Get notes
29    pub fn notes(&self) -> &[ShieldedActionNote] {
30        match self {
31            ShieldedWithdrawalTransitionAction::V0(transition) => &transition.notes,
32        }
33    }
34    /// Get anchor
35    pub fn anchor(&self) -> &[u8; 32] {
36        match self {
37            ShieldedWithdrawalTransitionAction::V0(transition) => &transition.anchor,
38        }
39    }
40    /// Get core fee per byte
41    pub fn core_fee_per_byte(&self) -> u32 {
42        match self {
43            ShieldedWithdrawalTransitionAction::V0(transition) => transition.core_fee_per_byte,
44        }
45    }
46    /// Get pooling strategy
47    pub fn pooling(&self) -> Pooling {
48        match self {
49            ShieldedWithdrawalTransitionAction::V0(transition) => transition.pooling,
50        }
51    }
52    /// Get output script
53    pub fn output_script(&self) -> &CoreScript {
54        match self {
55            ShieldedWithdrawalTransitionAction::V0(transition) => &transition.output_script,
56        }
57    }
58    /// Fee amount (value_balance - amount), paid to proposers
59    pub fn fee_amount(&self) -> Credits {
60        match self {
61            ShieldedWithdrawalTransitionAction::V0(transition) => transition.fee_amount,
62        }
63    }
64    /// Get prepared withdrawal document
65    pub fn prepared_withdrawal_document(&self) -> &Document {
66        match self {
67            ShieldedWithdrawalTransitionAction::V0(transition) => {
68                &transition.prepared_withdrawal_document
69            }
70        }
71    }
72    /// Get prepared withdrawal document owned
73    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}