@@ -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.
@@ -41,7 +41,7 @@ impl DynamicValidator {
4141 }
4242 }
4343
44- fn validators ( & self , parent : BlockHash ) -> Option < Vec < Validator > > {
44+ fn next_validators ( & self , parent : BlockHash ) -> Option < Vec < Validator > > {
4545 let client: Arc < dyn ConsensusClient > =
4646 self . client . read ( ) . as_ref ( ) . and_then ( Weak :: upgrade) . expect ( "Client is not initialized" ) ;
4747 let block_id = parent. into ( ) ;
@@ -64,19 +64,84 @@ impl DynamicValidator {
6464 }
6565 }
6666
67+ fn current_validators ( & self , hash : BlockHash ) -> Option < Vec < Validator > > {
68+ let client: Arc < dyn ConsensusClient > =
69+ self . client . read ( ) . as_ref ( ) . and_then ( Weak :: upgrade) . expect ( "Client is not initialized" ) ;
70+ let block_id = hash. into ( ) ;
71+ let term_id = client. current_term_id ( block_id) . expect (
72+ "valdators() is called when creating a block or verifying a block.
73+ Minor creates a block only when the parent block is imported.
74+ The n'th block is verified only when the parent block is imported." ,
75+ ) ;
76+ if term_id == 0 {
77+ return None
78+ }
79+ let state = client. state_at ( block_id) ?;
80+ let validators = CurrentValidators :: load_from_state ( & state) . unwrap ( ) ;
81+ if validators. is_empty ( ) {
82+ None
83+ } else {
84+ let mut validators: Vec < _ > = ( * validators) . clone ( ) ;
85+ validators. reverse ( ) ;
86+ Some ( validators)
87+ }
88+ }
89+
6790 fn validators_pubkey ( & self , parent : BlockHash ) -> Option < Vec < Public > > {
68- self . validators ( parent) . map ( |validators| validators. into_iter ( ) . map ( |val| * val. pubkey ( ) ) . collect ( ) )
91+ self . next_validators ( parent) . map ( |validators| validators. into_iter ( ) . map ( |val| * val. pubkey ( ) ) . collect ( ) )
6992 }
7093
7194 pub fn proposer_index ( & self , parent : BlockHash , prev_proposer_index : usize , proposed_view : usize ) -> usize {
72- if let Some ( validators) = self . validators ( parent) {
95+ if let Some ( validators) = self . next_validators ( parent) {
7396 let num_validators = validators. len ( ) ;
7497 proposed_view % num_validators
7598 } else {
7699 let num_validators = self . initial_list . count ( & parent) ;
77100 ( prev_proposer_index + proposed_view + 1 ) % num_validators
78101 }
79102 }
103+
104+ pub fn check_enough_votes_with_validators (
105+ & self ,
106+ validators : & [ Validator ] ,
107+ votes : & BitSet ,
108+ ) -> Result < ( ) , EngineError > {
109+ let mut voted_delegation = 0u64 ;
110+ let n_validators = validators. len ( ) ;
111+ for index in votes. true_index_iter ( ) {
112+ assert ! ( index < n_validators) ;
113+ let validator = validators. get ( index) . ok_or_else ( || {
114+ EngineError :: ValidatorNotExist {
115+ height : 0 , // FIXME
116+ index,
117+ }
118+ } ) ?;
119+ voted_delegation += validator. delegation ( ) ;
120+ }
121+ let total_delegation: u64 = validators. iter ( ) . map ( Validator :: delegation) . sum ( ) ;
122+ if voted_delegation * 3 > total_delegation * 2 {
123+ Ok ( ( ) )
124+ } else {
125+ let threshold = total_delegation as usize * 2 / 3 ;
126+ Err ( EngineError :: BadSealFieldSize ( OutOfBounds {
127+ min : Some ( threshold) ,
128+ max : Some ( total_delegation as usize ) ,
129+ found : voted_delegation as usize ,
130+ } ) )
131+ }
132+ }
133+
134+ pub fn check_enough_votes_with_header ( & self , header : & Header , votes : & BitSet ) -> Result < ( ) , EngineError > {
135+ let hash = header. hash ( ) ;
136+ let parent = * header. parent_hash ( ) ;
137+ let validators = self . current_validators ( hash) . or_else ( move || self . next_validators ( parent) ) ;
138+
139+ if let Some ( validators) = validators {
140+ self . check_enough_votes_with_validators ( & validators, votes)
141+ } else {
142+ self . initial_list . check_enough_votes ( header. parent_hash ( ) , votes)
143+ }
144+ }
80145}
81146
82147impl ValidatorSet for DynamicValidator {
@@ -136,38 +201,16 @@ impl ValidatorSet for DynamicValidator {
136201 }
137202
138203 fn count ( & self , parent : & BlockHash ) -> usize {
139- if let Some ( validators) = self . validators ( * parent) {
204+ if let Some ( validators) = self . next_validators ( * parent) {
140205 validators. len ( )
141206 } else {
142207 self . initial_list . count ( parent)
143208 }
144209 }
145210
146211 fn check_enough_votes ( & self , parent : & BlockHash , votes : & BitSet ) -> Result < ( ) , EngineError > {
147- 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- }
212+ if let Some ( validators) = self . next_validators ( * parent) {
213+ self . check_enough_votes_with_validators ( & validators, votes)
171214 } else {
172215 self . initial_list . check_enough_votes ( parent, votes)
173216 }
0 commit comments