@@ -18,13 +18,13 @@ use std::sync::{Arc, Weak};
18
18
19
19
use ckey:: { public_to_address, Address , Public } ;
20
20
use ctypes:: util:: unexpected:: OutOfBounds ;
21
- use ctypes:: BlockHash ;
21
+ use ctypes:: { BlockHash , Header } ;
22
22
use parking_lot:: RwLock ;
23
23
24
24
use super :: { RoundRobinValidator , ValidatorSet } ;
25
25
use crate :: client:: ConsensusClient ;
26
26
use crate :: consensus:: bit_set:: BitSet ;
27
- use crate :: consensus:: stake:: { get_validators, Validator } ;
27
+ use crate :: consensus:: stake:: { get_validators, CurrentValidators , Validator } ;
28
28
use crate :: consensus:: EngineError ;
29
29
30
30
/// Validator set containing a known set of public keys.
@@ -77,6 +77,58 @@ impl DynamicValidator {
77
77
( prev_proposer_index + proposed_view + 1 ) % num_validators
78
78
}
79
79
}
80
+
81
+ pub fn check_enough_votes_with_validators (
82
+ & self ,
83
+ validators : & [ Validator ] ,
84
+ votes : & BitSet ,
85
+ ) -> Result < ( ) , EngineError > {
86
+ let mut voted_delegation = 0u64 ;
87
+ let n_validators = validators. len ( ) ;
88
+ for index in votes. true_index_iter ( ) {
89
+ assert ! ( index < n_validators) ;
90
+ let validator = validators. get ( index) . ok_or_else ( || {
91
+ EngineError :: ValidatorNotExist {
92
+ height : 0 , // FIXME
93
+ index,
94
+ }
95
+ } ) ?;
96
+ voted_delegation += validator. delegation ( ) ;
97
+ }
98
+ let total_delegation: u64 = validators. iter ( ) . map ( Validator :: delegation) . sum ( ) ;
99
+ if voted_delegation * 3 > total_delegation * 2 {
100
+ Ok ( ( ) )
101
+ } else {
102
+ let threshold = total_delegation as usize * 2 / 3 ;
103
+ Err ( EngineError :: BadSealFieldSize ( OutOfBounds {
104
+ min : Some ( threshold) ,
105
+ max : Some ( total_delegation as usize ) ,
106
+ found : voted_delegation as usize ,
107
+ } ) )
108
+ }
109
+ }
110
+
111
+ pub fn check_enough_votes_with_header ( & self , header : & Header , votes : & BitSet ) -> Result < ( ) , EngineError > {
112
+ let client: Arc < dyn ConsensusClient > =
113
+ self . client . read ( ) . as_ref ( ) . and_then ( Weak :: upgrade) . expect ( "Client is not initialized" ) ;
114
+
115
+ let validators = {
116
+ match client. state_at ( header. hash ( ) . into ( ) ) . map ( |s| CurrentValidators :: load_from_state ( & s) ) {
117
+ Some ( Ok ( current_validators) ) if !current_validators. is_empty ( ) => {
118
+ let mut result = ( * current_validators) . clone ( ) ;
119
+ result. reverse ( ) ;
120
+ Some ( result)
121
+ }
122
+ _ => self . validators ( * header. parent_hash ( ) ) ,
123
+ }
124
+ } ;
125
+
126
+ if let Some ( validators) = validators {
127
+ self . check_enough_votes_with_validators ( & validators, votes)
128
+ } else {
129
+ self . initial_list . check_enough_votes ( header. parent_hash ( ) , votes)
130
+ }
131
+ }
80
132
}
81
133
82
134
impl ValidatorSet for DynamicValidator {
@@ -145,29 +197,7 @@ impl ValidatorSet for DynamicValidator {
145
197
146
198
fn check_enough_votes ( & self , parent : & BlockHash , votes : & BitSet ) -> Result < ( ) , EngineError > {
147
199
if let Some ( validators) = self . validators ( * parent) {
148
- let mut voted_delegation = 0u64 ;
149
- let n_validators = validators. len ( ) ;
150
- for index in votes. true_index_iter ( ) {
151
- assert ! ( index < n_validators) ;
152
- let validator = validators. get ( index) . ok_or_else ( || {
153
- EngineError :: ValidatorNotExist {
154
- height : 0 , // FIXME
155
- index,
156
- }
157
- } ) ?;
158
- voted_delegation += validator. delegation ( ) ;
159
- }
160
- let total_delegation: u64 = validators. iter ( ) . map ( Validator :: delegation) . sum ( ) ;
161
- if voted_delegation * 3 > total_delegation * 2 {
162
- Ok ( ( ) )
163
- } else {
164
- let threshold = total_delegation as usize * 2 / 3 ;
165
- Err ( EngineError :: BadSealFieldSize ( OutOfBounds {
166
- min : Some ( threshold) ,
167
- max : Some ( total_delegation as usize ) ,
168
- found : voted_delegation as usize ,
169
- } ) )
170
- }
200
+ self . check_enough_votes_with_validators ( & validators, votes)
171
201
} else {
172
202
self . initial_list . check_enough_votes ( parent, votes)
173
203
}
0 commit comments