@@ -18,13 +18,13 @@ use std::sync::{Arc, Weak};
1818
1919use ckey:: { public_to_address, Address , Public } ;
2020use ctypes:: util:: unexpected:: OutOfBounds ;
21- use ctypes:: BlockHash ;
21+ use ctypes:: { BlockHash , Header } ;
2222use parking_lot:: RwLock ;
2323
2424use super :: { RoundRobinValidator , ValidatorSet } ;
2525use crate :: client:: ConsensusClient ;
2626use crate :: consensus:: bit_set:: BitSet ;
27- use crate :: consensus:: stake:: { get_validators, Validator } ;
27+ use crate :: consensus:: stake:: { get_validators, CurrentValidators , Validator } ;
2828use crate :: consensus:: EngineError ;
2929
3030/// Validator set containing a known set of public keys.
@@ -77,6 +77,55 @@ impl DynamicValidator {
7777 ( prev_proposer_index + proposed_view + 1 ) % num_validators
7878 }
7979 }
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 ( ) => Some ( ( * current_validators) . clone ( ) ) ,
118+ _ => self . validators ( * header. parent_hash ( ) ) ,
119+ }
120+ } ;
121+
122+ if let Some ( mut validators) = validators {
123+ validators. reverse ( ) ;
124+ self . check_enough_votes_with_validators ( & validators, votes)
125+ } else {
126+ self . initial_list . check_enough_votes ( header. parent_hash ( ) , votes)
127+ }
128+ }
80129}
81130
82131impl ValidatorSet for DynamicValidator {
@@ -145,29 +194,7 @@ impl ValidatorSet for DynamicValidator {
145194
146195 fn check_enough_votes ( & self , parent : & BlockHash , votes : & BitSet ) -> Result < ( ) , EngineError > {
147196 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- }
197+ self . check_enough_votes_with_validators ( & validators, votes)
171198 } else {
172199 self . initial_list . check_enough_votes ( parent, votes)
173200 }
0 commit comments