@@ -82,21 +82,22 @@ pub enum VoteType {
82
82
SingleChoice ,
83
83
84
84
/// Multiple options can be selected with up to max_voter_options per voter
85
- /// and with up to max_executable_options of wining options eligible for execution
85
+ /// and with up to max_winning_options of successful options
86
86
/// Ex. voters are given 5 options, can choose up to 3 (max_voter_options)
87
- /// and only 1 (max_executable_options) wining option can be executed
87
+ /// and only 1 (max_winning_options) option can win and be executed
88
88
MultiChoice {
89
89
/// The max number of options a voter can choose
90
90
/// By default it equals to the number of available options
91
91
/// Note: In the current version the limit is not supported and not enforced yet
92
92
#[ allow( dead_code) ]
93
93
max_voter_options : u16 ,
94
94
95
- /// The max number of wining options which can be executed
95
+ /// The max number of wining options
96
+ /// For executable proposals it limits how many options can be executed for a Proposal
96
97
/// By default it equals to the number of available options
97
98
/// Note: In the current version the limit is not supported and not enforced yet
98
99
#[ allow( dead_code) ]
99
- max_executable_options : u16 ,
100
+ max_winning_options : u16 ,
100
101
} ,
101
102
}
102
103
@@ -132,12 +133,24 @@ pub struct ProposalV2 {
132
133
/// Proposal options
133
134
pub options : Vec < ProposalOption > ,
134
135
135
- /// The weight of the Proposal rejection votes
136
+ /// The total weight of the Proposal rejection votes
136
137
/// If the proposal has no deny option then the weight is None
137
138
/// Only proposals with the deny option can have executable instructions attached to them
138
139
/// Without the deny option a proposal is only non executable survey
139
140
pub deny_vote_weight : Option < u64 > ,
140
141
142
+ /// The total weight of Veto votes
143
+ /// Note: Veto is not supported in the current version
144
+ pub veto_vote_weight : Option < u64 > ,
145
+
146
+ /// The total weight of votes
147
+ /// Note: Abstain is not supported in the current version
148
+ pub abstain_vote_weight : Option < u64 > ,
149
+
150
+ /// Optional start time if the Proposal should not enter voting state immediately after being signed off
151
+ /// Note: start_at is not supported in the current version
152
+ pub start_voting_at : Option < UnixTimestamp > ,
153
+
141
154
/// When the Proposal was created and entered Draft state
142
155
pub draft_at : UnixTimestamp ,
143
156
@@ -169,11 +182,19 @@ pub struct ProposalV2 {
169
182
/// after vote was completed.
170
183
pub max_vote_weight : Option < u64 > ,
171
184
185
+ /// Max voting time for the proposal if different from parent Governance (only higher value possible)
186
+ /// Note: This field is not used in the current version
187
+ pub max_voting_time : Option < u32 > ,
188
+
172
189
/// The vote threshold percentage at the time Proposal was decided
173
190
/// It's used to show correct vote results for historical proposals in cases when the threshold
174
191
/// was changed for governance config after vote was completed.
192
+ /// TODO: Use this field to override for the threshold from parent Governance (only higher value possible)
175
193
pub vote_threshold_percentage : Option < VoteThresholdPercentage > ,
176
194
195
+ /// Reserved space for future versions
196
+ pub reserved : [ u8 ; 8 ] ,
197
+
177
198
/// Proposal name
178
199
pub name : String ,
179
200
@@ -184,7 +205,7 @@ pub struct ProposalV2 {
184
205
impl AccountMaxSize for ProposalV2 {
185
206
fn get_max_size ( & self ) -> Option < usize > {
186
207
let options_size: usize = self . options . iter ( ) . map ( |o| o. label . len ( ) + 19 ) . sum ( ) ;
187
- Some ( self . name . len ( ) + self . description_link . len ( ) + options_size + 201 )
208
+ Some ( self . name . len ( ) + self . description_link . len ( ) + options_size + 241 )
188
209
}
189
210
}
190
211
@@ -372,7 +393,7 @@ impl ProposalV2 {
372
393
}
373
394
VoteType :: MultiChoice {
374
395
max_voter_options : _n,
375
- max_executable_options : _m,
396
+ max_winning_options : _m,
376
397
} => {
377
398
// If any option succeeded for multi choice then the proposal as a whole succeeded as well
378
399
ProposalState :: Succeeded
@@ -708,7 +729,7 @@ impl ProposalV2 {
708
729
}
709
730
VoteType :: MultiChoice {
710
731
max_voter_options : _n,
711
- max_executable_options : _m,
732
+ max_winning_options : _m,
712
733
} => {
713
734
if choice_count == 0 {
714
735
return Err ( GovernanceError :: InvalidVote . into ( ) ) ;
@@ -721,6 +742,9 @@ impl ProposalV2 {
721
742
return Err ( GovernanceError :: InvalidVote . into ( ) ) ;
722
743
}
723
744
}
745
+ Vote :: Abstain | Vote :: Veto => {
746
+ return Err ( GovernanceError :: NotSupportedVoteType . into ( ) ) ;
747
+ }
724
748
}
725
749
726
750
Ok ( ( ) )
@@ -733,6 +757,22 @@ impl ProposalV2 {
733
757
} else if self . account_type == GovernanceAccountType :: ProposalV1 {
734
758
// V1 account can't be resized and we have to translate it back to the original format
735
759
760
+ if self . abstain_vote_weight . is_some ( ) {
761
+ panic ! ( "ProposalV1 doesn't support Abstain vote" )
762
+ }
763
+
764
+ if self . veto_vote_weight . is_some ( ) {
765
+ panic ! ( "ProposalV1 doesn't support Veto vote" )
766
+ }
767
+
768
+ if self . start_voting_at . is_some ( ) {
769
+ panic ! ( "ProposalV1 doesn't support start time" )
770
+ }
771
+
772
+ if self . max_voting_time . is_some ( ) {
773
+ panic ! ( "ProposalV1 doesn't support max voting time" )
774
+ }
775
+
736
776
let proposal_data_v1 = ProposalV1 {
737
777
account_type : self . account_type ,
738
778
governance : self . governance ,
@@ -837,6 +877,9 @@ pub fn get_proposal_data(
837
877
transactions_next_index: proposal_data_v1. instructions_next_index,
838
878
} ] ,
839
879
deny_vote_weight : Some ( proposal_data_v1. no_votes_count ) ,
880
+ veto_vote_weight : None ,
881
+ abstain_vote_weight : None ,
882
+ start_voting_at : None ,
840
883
draft_at : proposal_data_v1. draft_at ,
841
884
signing_off_at : proposal_data_v1. signing_off_at ,
842
885
voting_at : proposal_data_v1. voting_at ,
@@ -846,9 +889,11 @@ pub fn get_proposal_data(
846
889
closed_at : proposal_data_v1. closed_at ,
847
890
execution_flags : proposal_data_v1. execution_flags ,
848
891
max_vote_weight : proposal_data_v1. max_vote_weight ,
892
+ max_voting_time : None ,
849
893
vote_threshold_percentage : proposal_data_v1. vote_threshold_percentage ,
850
894
name : proposal_data_v1. name ,
851
895
description_link : proposal_data_v1. description_link ,
896
+ reserved : [ 0 ; 8 ] ,
852
897
} ) ;
853
898
}
854
899
@@ -925,17 +970,20 @@ pub fn assert_valid_proposal_options(
925
970
926
971
if let VoteType :: MultiChoice {
927
972
max_voter_options,
928
- max_executable_options ,
973
+ max_winning_options ,
929
974
} = * vote_type
930
975
{
931
976
if options. len ( ) == 1
932
977
|| max_voter_options as usize != options. len ( )
933
- || max_executable_options as usize != options. len ( )
978
+ || max_winning_options as usize != options. len ( )
934
979
{
935
980
return Err ( GovernanceError :: InvalidProposalOptions . into ( ) ) ;
936
981
}
937
982
}
938
983
984
+ // TODO: Check for duplicated option labels
985
+ // The options are identified by index so it's ok for now
986
+
939
987
if options. iter ( ) . any ( |o| o. is_empty ( ) ) {
940
988
return Err ( GovernanceError :: InvalidProposalOptions . into ( ) ) ;
941
989
}
@@ -969,6 +1017,8 @@ mod test {
969
1017
signatories_signed_off_count : 5 ,
970
1018
description_link : "This is my description" . to_string ( ) ,
971
1019
name : "This is my name" . to_string ( ) ,
1020
+
1021
+ start_voting_at : Some ( 0 ) ,
972
1022
draft_at : 10 ,
973
1023
signing_off_at : Some ( 10 ) ,
974
1024
@@ -989,10 +1039,15 @@ mod test {
989
1039
transactions_next_index: 10 ,
990
1040
} ] ,
991
1041
deny_vote_weight : Some ( 0 ) ,
1042
+ abstain_vote_weight : Some ( 0 ) ,
1043
+ veto_vote_weight : Some ( 0 ) ,
992
1044
993
1045
execution_flags : InstructionExecutionFlags :: Ordered ,
994
1046
1047
+ max_voting_time : Some ( 0 ) ,
995
1048
vote_threshold_percentage : Some ( VoteThresholdPercentage :: YesVote ( 100 ) ) ,
1049
+
1050
+ reserved : [ 0 ; 8 ] ,
996
1051
}
997
1052
}
998
1053
@@ -1066,7 +1121,7 @@ mod test {
1066
1121
let mut proposal = create_test_proposal ( ) ;
1067
1122
proposal. vote_type = VoteType :: MultiChoice {
1068
1123
max_voter_options : 1 ,
1069
- max_executable_options : 1 ,
1124
+ max_winning_options : 1 ,
1070
1125
} ;
1071
1126
1072
1127
let size = proposal. try_to_vec ( ) . unwrap ( ) . len ( ) ;
@@ -1079,7 +1134,7 @@ mod test {
1079
1134
let mut proposal = create_test_multi_option_proposal ( ) ;
1080
1135
proposal. vote_type = VoteType :: MultiChoice {
1081
1136
max_voter_options : 3 ,
1082
- max_executable_options : 3 ,
1137
+ max_winning_options : 3 ,
1083
1138
} ;
1084
1139
1085
1140
let size = proposal. try_to_vec ( ) . unwrap ( ) . len ( ) ;
@@ -2025,7 +2080,7 @@ mod test {
2025
2080
let mut proposal = create_test_multi_option_proposal ( ) ;
2026
2081
proposal. vote_type = VoteType :: MultiChoice {
2027
2082
max_voter_options : 3 ,
2028
- max_executable_options : 3 ,
2083
+ max_winning_options : 3 ,
2029
2084
} ;
2030
2085
2031
2086
let choices = vec ! [
@@ -2061,7 +2116,7 @@ mod test {
2061
2116
// Arrange
2062
2117
let vote_type = VoteType :: MultiChoice {
2063
2118
max_voter_options : 3 ,
2064
- max_executable_options : 3 ,
2119
+ max_winning_options : 3 ,
2065
2120
} ;
2066
2121
2067
2122
let options = vec ! [ "option 1" . to_string( ) , "option 2" . to_string( ) ] ;
@@ -2078,7 +2133,7 @@ mod test {
2078
2133
// Arrange
2079
2134
let vote_type = VoteType :: MultiChoice {
2080
2135
max_voter_options : 3 ,
2081
- max_executable_options : 3 ,
2136
+ max_winning_options : 3 ,
2082
2137
} ;
2083
2138
2084
2139
let options = vec ! [ ] ;
@@ -2109,7 +2164,7 @@ mod test {
2109
2164
// Arrange
2110
2165
let vote_type = VoteType :: MultiChoice {
2111
2166
max_voter_options : 3 ,
2112
- max_executable_options : 3 ,
2167
+ max_winning_options : 3 ,
2113
2168
} ;
2114
2169
2115
2170
let options = vec ! [
@@ -2130,7 +2185,7 @@ mod test {
2130
2185
// Arrange
2131
2186
let vote_type = VoteType :: MultiChoice {
2132
2187
max_voter_options : 3 ,
2133
- max_executable_options : 3 ,
2188
+ max_winning_options : 3 ,
2134
2189
} ;
2135
2190
2136
2191
let options = vec ! [
0 commit comments