drive/state_transition_action/shielded/unshield/
mod.rs1pub mod transformer;
3pub mod v0;
5
6use crate::state_transition_action::shielded::unshield::v0::UnshieldTransitionActionV0;
7use crate::state_transition_action::shielded::ShieldedActionNote;
8use derive_more::From;
9use dpp::address_funds::PlatformAddress;
10use dpp::fee::Credits;
11
12#[derive(Debug, Clone, From)]
14pub enum UnshieldTransitionAction {
15 V0(UnshieldTransitionActionV0),
17}
18
19impl UnshieldTransitionAction {
20 pub fn output_address(&self) -> &PlatformAddress {
22 match self {
23 UnshieldTransitionAction::V0(transition) => &transition.output_address,
24 }
25 }
26 pub fn amount(&self) -> Credits {
28 match self {
29 UnshieldTransitionAction::V0(transition) => transition.amount,
30 }
31 }
32 pub fn notes(&self) -> &[ShieldedActionNote] {
34 match self {
35 UnshieldTransitionAction::V0(transition) => &transition.notes,
36 }
37 }
38 pub fn anchor(&self) -> &[u8; 32] {
40 match self {
41 UnshieldTransitionAction::V0(transition) => &transition.anchor,
42 }
43 }
44 pub fn fee_amount(&self) -> Credits {
46 match self {
47 UnshieldTransitionAction::V0(transition) => transition.fee_amount,
48 }
49 }
50 pub fn chargeable_failure(&self) -> bool {
53 match self {
54 UnshieldTransitionAction::V0(transition) => transition.chargeable_failure,
55 }
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 fn make_note() -> ShieldedActionNote {
64 ShieldedActionNote {
65 nullifier: [0x33; 32],
66 cmx: [0x44; 32],
67 cv_net: [0x22; 32],
68 encrypted_note: vec![0x10, 0x20],
69 }
70 }
71
72 fn make_action() -> UnshieldTransitionAction {
73 let v0 = UnshieldTransitionActionV0 {
74 output_address: PlatformAddress::P2pkh([0xBB; 20]),
75 amount: 7500,
76 notes: vec![make_note()],
77 anchor: [0x55; 32],
78 fee_amount: 250,
79 current_total_balance: 100000,
80 chargeable_failure: false,
81 };
82 UnshieldTransitionAction::from(v0)
83 }
84
85 #[test]
86 fn test_from_v0() {
87 let action = make_action();
88 assert!(matches!(action, UnshieldTransitionAction::V0(_)));
89 }
90
91 #[test]
92 fn test_output_address() {
93 let action = make_action();
94 assert_eq!(*action.output_address(), PlatformAddress::P2pkh([0xBB; 20]));
95 }
96
97 #[test]
98 fn test_amount() {
99 let action = make_action();
100 assert_eq!(action.amount(), 7500);
101 }
102
103 #[test]
104 fn test_notes() {
105 let action = make_action();
106 let notes = action.notes();
107 assert_eq!(notes.len(), 1);
108 assert_eq!(notes[0].nullifier, [0x33; 32]);
109 assert_eq!(notes[0].cmx, [0x44; 32]);
110 }
111
112 #[test]
113 fn test_anchor() {
114 let action = make_action();
115 assert_eq!(*action.anchor(), [0x55; 32]);
116 }
117
118 #[test]
119 fn test_fee_amount() {
120 let action = make_action();
121 assert_eq!(action.fee_amount(), 250);
122 }
123
124 #[test]
125 fn test_zero_fee_amount() {
126 let v0 = UnshieldTransitionActionV0 {
127 output_address: PlatformAddress::P2sh([0x00; 20]),
128 amount: 0,
129 notes: vec![],
130 anchor: [0x00; 32],
131 fee_amount: 0,
132 current_total_balance: 0,
133 chargeable_failure: false,
134 };
135 let action = UnshieldTransitionAction::from(v0);
136 assert_eq!(action.amount(), 0);
137 assert_eq!(action.fee_amount(), 0);
138 assert!(action.notes().is_empty());
139 }
140
141 #[test]
142 fn test_clone() {
143 let action = make_action();
144 let cloned = action.clone();
145 assert_eq!(cloned.amount(), 7500);
146 assert_eq!(cloned.fee_amount(), 250);
147 assert_eq!(*cloned.anchor(), [0x55; 32]);
148 }
149
150 #[test]
151 fn test_debug() {
152 let action = make_action();
153 let debug_str = format!("{:?}", action);
154 assert!(debug_str.contains("V0"));
155 }
156}