drive/state_transition_action/shielded/shield/
mod.rs1pub mod transformer;
3pub mod v0;
5
6use crate::state_transition_action::shielded::shield::v0::ShieldTransitionActionV0;
7use crate::state_transition_action::shielded::ShieldedActionNote;
8use derive_more::From;
9use dpp::address_funds::{AddressFundsFeeStrategy, PlatformAddress};
10use dpp::fee::Credits;
11use dpp::prelude::{AddressNonce, UserFeeIncrease};
12use std::collections::BTreeMap;
13
14#[derive(Debug, Clone, From)]
16pub enum ShieldTransitionAction {
17 V0(ShieldTransitionActionV0),
19}
20
21impl ShieldTransitionAction {
22 pub fn inputs_with_remaining_balance(
24 &self,
25 ) -> &BTreeMap<PlatformAddress, (AddressNonce, Credits)> {
26 match self {
27 ShieldTransitionAction::V0(transition) => &transition.inputs_with_remaining_balance,
28 }
29 }
30 pub fn shield_amount(&self) -> Credits {
32 match self {
33 ShieldTransitionAction::V0(transition) => transition.shield_amount,
34 }
35 }
36 pub fn notes(&self) -> &[ShieldedActionNote] {
38 match self {
39 ShieldTransitionAction::V0(transition) => &transition.notes,
40 }
41 }
42 pub fn user_fee_increase(&self) -> UserFeeIncrease {
44 match self {
45 ShieldTransitionAction::V0(transition) => transition.user_fee_increase,
46 }
47 }
48 pub fn fee_strategy(&self) -> &AddressFundsFeeStrategy {
50 match self {
51 ShieldTransitionAction::V0(transition) => &transition.fee_strategy,
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use dpp::address_funds::fee_strategy::AddressFundsFeeStrategyStep;
60
61 fn make_note() -> ShieldedActionNote {
62 ShieldedActionNote {
63 nullifier: [0x11; 32],
64 cmx: [0x22; 32],
65 cv_net: [0x22; 32],
66 encrypted_note: vec![0xAB, 0xCD, 0xEF],
67 }
68 }
69
70 fn make_action() -> ShieldTransitionAction {
71 let addr = PlatformAddress::P2pkh([0xAA; 20]);
72 let mut inputs = BTreeMap::new();
73 inputs.insert(addr, (3_u32, 10000_u64));
74
75 let v0 = ShieldTransitionActionV0 {
76 inputs_with_remaining_balance: inputs,
77 shield_amount: 5000,
78 notes: vec![make_note(), make_note()],
79 fee_strategy: vec![AddressFundsFeeStrategyStep::DeductFromInput(0)],
80 user_fee_increase: 2,
81 current_total_balance: 50000,
82 };
83 ShieldTransitionAction::from(v0)
84 }
85
86 #[test]
87 fn test_from_v0() {
88 let action = make_action();
89 assert!(matches!(action, ShieldTransitionAction::V0(_)));
90 }
91
92 #[test]
93 fn test_inputs_with_remaining_balance() {
94 let action = make_action();
95 let inputs = action.inputs_with_remaining_balance();
96 assert_eq!(inputs.len(), 1);
97 let addr = PlatformAddress::P2pkh([0xAA; 20]);
98 let (nonce, balance) = inputs.get(&addr).unwrap();
99 assert_eq!(*nonce, 3);
100 assert_eq!(*balance, 10000);
101 }
102
103 #[test]
104 fn test_shield_amount() {
105 let action = make_action();
106 assert_eq!(action.shield_amount(), 5000);
107 }
108
109 #[test]
110 fn test_notes() {
111 let action = make_action();
112 let notes = action.notes();
113 assert_eq!(notes.len(), 2);
114 assert_eq!(notes[0].nullifier, [0x11; 32]);
115 assert_eq!(notes[0].cmx, [0x22; 32]);
116 assert_eq!(notes[0].encrypted_note, vec![0xAB, 0xCD, 0xEF]);
117 }
118
119 #[test]
120 fn test_user_fee_increase() {
121 let action = make_action();
122 assert_eq!(action.user_fee_increase(), 2);
123 }
124
125 #[test]
126 fn test_fee_strategy() {
127 let action = make_action();
128 let strategy = action.fee_strategy();
129 assert_eq!(strategy.len(), 1);
130 assert!(matches!(
131 strategy[0],
132 AddressFundsFeeStrategyStep::DeductFromInput(0)
133 ));
134 }
135
136 #[test]
137 fn test_empty_notes() {
138 let v0 = ShieldTransitionActionV0 {
139 inputs_with_remaining_balance: BTreeMap::new(),
140 shield_amount: 0,
141 notes: vec![],
142 fee_strategy: vec![],
143 user_fee_increase: 0,
144 current_total_balance: 0,
145 };
146 let action = ShieldTransitionAction::from(v0);
147 assert!(action.notes().is_empty());
148 assert_eq!(action.shield_amount(), 0);
149 }
150
151 #[test]
152 fn test_clone() {
153 let action = make_action();
154 let cloned = action.clone();
155 assert_eq!(cloned.shield_amount(), 5000);
156 assert_eq!(cloned.notes().len(), 2);
157 assert_eq!(cloned.user_fee_increase(), 2);
158 }
159
160 #[test]
161 fn test_debug() {
162 let action = make_action();
163 let debug_str = format!("{:?}", action);
164 assert!(debug_str.contains("V0"));
165 }
166}