drive/state_transition_action/identity/masternode_vote/
mod.rs

1/// transformer
2pub mod transformer;
3/// v0
4pub mod v0;
5
6use crate::drive::votes::resolved::votes::ResolvedVote;
7use crate::state_transition_action::identity::masternode_vote::v0::{
8    MasternodeVoteTransitionActionV0, PreviousVoteCount,
9};
10use derive_more::From;
11use dpp::platform_value::Identifier;
12use dpp::prelude::IdentityNonce;
13use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice;
14
15/// action
16#[derive(Debug, Clone, From)]
17pub enum MasternodeVoteTransitionAction {
18    /// v0
19    V0(MasternodeVoteTransitionActionV0),
20}
21
22impl MasternodeVoteTransitionAction {
23    /// the pro tx hash identifier of the masternode
24    pub fn pro_tx_hash(&self) -> Identifier {
25        match self {
26            MasternodeVoteTransitionAction::V0(transition) => transition.pro_tx_hash,
27        }
28    }
29
30    /// the voter identity id
31    pub fn voter_identity_id(&self) -> Identifier {
32        match self {
33            MasternodeVoteTransitionAction::V0(transition) => transition.voter_identity_id,
34        }
35    }
36
37    /// the masternode list state based voting address
38    pub fn voting_address(&self) -> [u8; 20] {
39        match self {
40            MasternodeVoteTransitionAction::V0(transition) => transition.voting_address,
41        }
42    }
43
44    /// Resource votes
45    pub fn vote_ref(&self) -> &ResolvedVote {
46        match self {
47            MasternodeVoteTransitionAction::V0(transition) => &transition.vote,
48        }
49    }
50
51    /// Resource votes as owned
52    pub fn vote_owned(self) -> ResolvedVote {
53        match self {
54            MasternodeVoteTransitionAction::V0(transition) => transition.vote,
55        }
56    }
57
58    /// Nonce
59    pub fn nonce(&self) -> IdentityNonce {
60        match self {
61            MasternodeVoteTransitionAction::V0(transition) => transition.nonce,
62        }
63    }
64
65    /// Vote strength
66    pub fn vote_strength(&self) -> u8 {
67        match self {
68            MasternodeVoteTransitionAction::V0(transition) => transition.vote_strength,
69        }
70    }
71
72    /// The previous resource vote choice that needs to be removed
73    pub fn take_previous_resource_vote_choice_to_remove(
74        &mut self,
75    ) -> Option<(ResourceVoteChoice, PreviousVoteCount)> {
76        match self {
77            MasternodeVoteTransitionAction::V0(transition) => {
78                transition.previous_resource_vote_choice_to_remove.take()
79            }
80        }
81    }
82
83    /// The previous resource vote choice that needs to be removed
84    pub fn previous_resource_vote_choice_to_remove(
85        &self,
86    ) -> &Option<(ResourceVoteChoice, PreviousVoteCount)> {
87        match self {
88            MasternodeVoteTransitionAction::V0(transition) => {
89                &transition.previous_resource_vote_choice_to_remove
90            }
91        }
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98    use crate::drive::votes::resolved::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePollWithContractInfo;
99    use crate::drive::votes::resolved::vote_polls::ResolvedVotePoll;
100    use crate::drive::votes::resolved::votes::resolved_resource_vote::v0::ResolvedResourceVoteV0;
101    use crate::drive::votes::resolved::votes::resolved_resource_vote::ResolvedResourceVote;
102    use crate::drive::votes::resolved::votes::ResolvedVote;
103    use crate::state_transition_action::identity::masternode_vote::v0::MasternodeVoteTransitionActionV0;
104    use crate::util::object_size_info::DataContractOwnedResolvedInfo;
105    use dpp::tests::fixtures::get_dpns_data_contract_fixture;
106    use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice;
107    use platform_version::version::PlatformVersion;
108
109    fn make_resolved_vote() -> ResolvedVote {
110        let platform_version = PlatformVersion::latest();
111        let dpns = get_dpns_data_contract_fixture(None, 0, platform_version.protocol_version);
112        let data_contract = dpns.data_contract_owned();
113        let contract_info = ContestedDocumentResourceVotePollWithContractInfo {
114            contract: DataContractOwnedResolvedInfo::OwnedDataContract(data_contract),
115            document_type_name: "domain".to_string(),
116            index_name: "parentNameAndLabel".to_string(),
117            index_values: vec![],
118        };
119        ResolvedVote::ResolvedResourceVote(ResolvedResourceVote::V0(ResolvedResourceVoteV0 {
120            resolved_vote_poll: ResolvedVotePoll::ContestedDocumentResourceVotePollWithContractInfo(
121                contract_info,
122            ),
123            resource_vote_choice: ResourceVoteChoice::Abstain,
124        }))
125    }
126
127    fn make_v0() -> MasternodeVoteTransitionActionV0 {
128        MasternodeVoteTransitionActionV0 {
129            pro_tx_hash: Identifier::from([0xAA; 32]),
130            voter_identity_id: Identifier::from([0xBB; 32]),
131            voting_address: [0xCC; 20],
132            vote_strength: 4,
133            vote: make_resolved_vote(),
134            previous_resource_vote_choice_to_remove: Some((ResourceVoteChoice::Lock, 2)),
135            nonce: 77,
136        }
137    }
138
139    #[test]
140    fn test_from_v0() {
141        let v0 = make_v0();
142        let action: MasternodeVoteTransitionAction = v0.into();
143        assert!(matches!(action, MasternodeVoteTransitionAction::V0(_)));
144    }
145
146    #[test]
147    fn test_pro_tx_hash() {
148        let action = MasternodeVoteTransitionAction::V0(make_v0());
149        assert_eq!(action.pro_tx_hash(), Identifier::from([0xAA; 32]));
150    }
151
152    #[test]
153    fn test_voter_identity_id() {
154        let action = MasternodeVoteTransitionAction::V0(make_v0());
155        assert_eq!(action.voter_identity_id(), Identifier::from([0xBB; 32]));
156    }
157
158    #[test]
159    fn test_voting_address() {
160        let action = MasternodeVoteTransitionAction::V0(make_v0());
161        assert_eq!(action.voting_address(), [0xCC; 20]);
162    }
163
164    #[test]
165    fn test_vote_ref() {
166        let action = MasternodeVoteTransitionAction::V0(make_v0());
167        let vote = action.vote_ref();
168        assert!(matches!(vote, ResolvedVote::ResolvedResourceVote(_)));
169    }
170
171    #[test]
172    fn test_vote_owned() {
173        let action = MasternodeVoteTransitionAction::V0(make_v0());
174        let vote = action.vote_owned();
175        assert!(matches!(vote, ResolvedVote::ResolvedResourceVote(_)));
176    }
177
178    #[test]
179    fn test_nonce() {
180        let action = MasternodeVoteTransitionAction::V0(make_v0());
181        assert_eq!(action.nonce(), 77);
182    }
183
184    #[test]
185    fn test_vote_strength() {
186        let action = MasternodeVoteTransitionAction::V0(make_v0());
187        assert_eq!(action.vote_strength(), 4);
188    }
189
190    #[test]
191    fn test_previous_resource_vote_choice_to_remove() {
192        let action = MasternodeVoteTransitionAction::V0(make_v0());
193        let prev = action.previous_resource_vote_choice_to_remove();
194        assert!(prev.is_some());
195        let (choice, count) = prev.as_ref().unwrap();
196        assert_eq!(*choice, ResourceVoteChoice::Lock);
197        assert_eq!(*count, 2);
198    }
199
200    #[test]
201    fn test_take_previous_resource_vote_choice_to_remove() {
202        let mut action = MasternodeVoteTransitionAction::V0(make_v0());
203        let taken = action.take_previous_resource_vote_choice_to_remove();
204        assert!(taken.is_some());
205        let (choice, count) = taken.unwrap();
206        assert_eq!(choice, ResourceVoteChoice::Lock);
207        assert_eq!(count, 2);
208        // After taking, it should be None
209        assert!(action.previous_resource_vote_choice_to_remove().is_none());
210    }
211
212    #[test]
213    fn test_previous_resource_vote_choice_none() {
214        let mut v0 = make_v0();
215        v0.previous_resource_vote_choice_to_remove = None;
216        let action = MasternodeVoteTransitionAction::V0(v0);
217        assert!(action.previous_resource_vote_choice_to_remove().is_none());
218    }
219}