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 encrypted_note: vec![0xAB, 0xCD, 0xEF],
66 }
67 }
68
69 fn make_action() -> ShieldTransitionAction {
70 let addr = PlatformAddress::P2pkh([0xAA; 20]);
71 let mut inputs = BTreeMap::new();
72 inputs.insert(addr, (3_u32, 10000_u64));
73
74 let v0 = ShieldTransitionActionV0 {
75 inputs_with_remaining_balance: inputs,
76 shield_amount: 5000,
77 notes: vec![make_note(), make_note()],
78 fee_strategy: vec![AddressFundsFeeStrategyStep::DeductFromInput(0)],
79 user_fee_increase: 2,
80 current_total_balance: 50000,
81 };
82 ShieldTransitionAction::from(v0)
83 }
84
85 #[test]
86 fn test_from_v0() {
87 let action = make_action();
88 assert!(matches!(action, ShieldTransitionAction::V0(_)));
89 }
90
91 #[test]
92 fn test_inputs_with_remaining_balance() {
93 let action = make_action();
94 let inputs = action.inputs_with_remaining_balance();
95 assert_eq!(inputs.len(), 1);
96 let addr = PlatformAddress::P2pkh([0xAA; 20]);
97 let (nonce, balance) = inputs.get(&addr).unwrap();
98 assert_eq!(*nonce, 3);
99 assert_eq!(*balance, 10000);
100 }
101
102 #[test]
103 fn test_shield_amount() {
104 let action = make_action();
105 assert_eq!(action.shield_amount(), 5000);
106 }
107
108 #[test]
109 fn test_notes() {
110 let action = make_action();
111 let notes = action.notes();
112 assert_eq!(notes.len(), 2);
113 assert_eq!(notes[0].nullifier, [0x11; 32]);
114 assert_eq!(notes[0].cmx, [0x22; 32]);
115 assert_eq!(notes[0].encrypted_note, vec![0xAB, 0xCD, 0xEF]);
116 }
117
118 #[test]
119 fn test_user_fee_increase() {
120 let action = make_action();
121 assert_eq!(action.user_fee_increase(), 2);
122 }
123
124 #[test]
125 fn test_fee_strategy() {
126 let action = make_action();
127 let strategy = action.fee_strategy();
128 assert_eq!(strategy.len(), 1);
129 assert!(matches!(
130 strategy[0],
131 AddressFundsFeeStrategyStep::DeductFromInput(0)
132 ));
133 }
134
135 #[test]
136 fn test_empty_notes() {
137 let v0 = ShieldTransitionActionV0 {
138 inputs_with_remaining_balance: BTreeMap::new(),
139 shield_amount: 0,
140 notes: vec![],
141 fee_strategy: vec![],
142 user_fee_increase: 0,
143 current_total_balance: 0,
144 };
145 let action = ShieldTransitionAction::from(v0);
146 assert!(action.notes().is_empty());
147 assert_eq!(action.shield_amount(), 0);
148 }
149
150 #[test]
151 fn test_clone() {
152 let action = make_action();
153 let cloned = action.clone();
154 assert_eq!(cloned.shield_amount(), 5000);
155 assert_eq!(cloned.notes().len(), 2);
156 assert_eq!(cloned.user_fee_increase(), 2);
157 }
158
159 #[test]
160 fn test_debug() {
161 let action = make_action();
162 let debug_str = format!("{:?}", action);
163 assert!(debug_str.contains("V0"));
164 }
165}