@@ -21,20 +21,24 @@ use std::sync::{Arc, Weak};
21
21
use std:: thread:: { Builder , JoinHandle } ;
22
22
use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
23
23
24
+ use ccrypto:: sha256;
24
25
use ckey:: { public_to_address, verify_schnorr, Address , SchnorrSignature } ;
25
26
use cnetwork:: { EventSender , NodeId } ;
26
27
use crossbeam_channel as crossbeam;
27
28
use ctypes:: transaction:: { Action , Transaction } ;
28
29
use ctypes:: util:: unexpected:: Mismatch ;
29
30
use ctypes:: { BlockHash , BlockNumber , Header } ;
31
+ use parking_lot:: RwLock ;
30
32
use primitives:: { u256_from_u128, Bytes , U256 } ;
31
33
use rlp:: { Encodable , Rlp } ;
34
+ use vrf:: openssl:: { CipherSuite , ECVRF } ;
32
35
33
36
use super :: super :: BitSet ;
34
37
use super :: backup:: { backup, restore, BackupView } ;
35
38
use super :: message:: * ;
36
39
use super :: network;
37
40
use super :: params:: TimeGapParams ;
41
+ use super :: sortition_info_collector:: SortitionInfoCollector ;
38
42
use super :: stake:: CUSTOM_ACTION_HANDLER_ID ;
39
43
use super :: types:: { Height , Proposal , Step , TendermintSealView , TendermintState , TwoThirdsMajority , View } ;
40
44
use super :: vote_collector:: { DoubleVote , VoteCollector } ;
@@ -47,7 +51,7 @@ use crate::block::*;
47
51
use crate :: client:: ConsensusClient ;
48
52
use crate :: consensus:: signer:: EngineSigner ;
49
53
use crate :: consensus:: validator_set:: { DynamicValidator , ValidatorSet } ;
50
- use crate :: consensus:: { EngineError , Seal } ;
54
+ use crate :: consensus:: { EngineError , Seal , VRFSortition } ;
51
55
use crate :: encoded;
52
56
use crate :: error:: { BlockError , Error } ;
53
57
use crate :: transaction:: { SignedTransaction , UnverifiedTransaction } ;
@@ -94,6 +98,9 @@ struct Worker {
94
98
validators : Arc < DynamicValidator > ,
95
99
/// Channel to the network extension, must be set later.
96
100
extension : EventSender < network:: Event > ,
101
+ /// VRF instance to calculate VRF hash.
102
+ vrf_inst : Arc < RwLock < ECVRF > > ,
103
+ sortition_infos : SortitionInfoCollector ,
97
104
time_gap_params : TimeGapParams ,
98
105
timeout_token_nonce : usize ,
99
106
vote_regression_checker : VoteRegressionChecker ,
@@ -137,6 +144,13 @@ pub enum Event {
137
144
address : Address ,
138
145
} ,
139
146
Restore ( crossbeam:: Sender < ( ) > ) ,
147
+ Priority {
148
+ height : Height ,
149
+ view : View ,
150
+ signer_idx : usize ,
151
+ message : PriorityMessage ,
152
+ result : crossbeam:: Sender < Option < Arc < dyn ConsensusClient > > > ,
153
+ } ,
140
154
ProposalBlock {
141
155
signature : SchnorrSignature ,
142
156
view : View ,
@@ -194,10 +208,12 @@ impl Worker {
194
208
finalized_view_of_current_block : None ,
195
209
validators,
196
210
extension,
211
+ sortition_infos : Default :: default ( ) ,
197
212
votes_received : MutTrigger :: new ( BitSet :: new ( ) ) ,
198
213
time_gap_params,
199
214
timeout_token_nonce : ENGINE_TIMEOUT_TOKEN_NONCE_BASE ,
200
215
vote_regression_checker : VoteRegressionChecker :: new ( ) ,
216
+ vrf_inst : Arc :: new ( RwLock :: new ( ECVRF :: from_suite ( CipherSuite :: SECP256K1_SHA256_SVDW ) . unwrap ( ) ) ) ,
201
217
}
202
218
}
203
219
@@ -312,6 +328,16 @@ impl Worker {
312
328
inner. restore( ) ;
313
329
result. send( ( ) ) . unwrap( ) ;
314
330
}
331
+ Ok ( Event :: Priority {
332
+ height,
333
+ view,
334
+ signer_idx,
335
+ message,
336
+ result,
337
+ } ) => {
338
+ let client = inner. on_priority_message( height, view, signer_idx, message) ;
339
+ result. send( client) . unwrap( ) ;
340
+ }
315
341
Ok ( Event :: ProposalBlock {
316
342
signature,
317
343
view,
@@ -1728,6 +1754,35 @@ impl Worker {
1728
1754
result. send ( message. rlp_bytes ( ) . into_vec ( ) ) . unwrap ( ) ;
1729
1755
}
1730
1756
1757
+ fn on_priority_message (
1758
+ & mut self ,
1759
+ height : Height ,
1760
+ view : View ,
1761
+ signer_idx : usize ,
1762
+ message : PriorityMessage ,
1763
+ ) -> Option < Arc < dyn ConsensusClient > > {
1764
+ let c = self . client . upgrade ( ) ?;
1765
+ c. block_hash ( & BlockId :: Number ( height - 1 ) ) . and_then ( |parent_hash| {
1766
+ let signer_public = self . validators . get ( & parent_hash, signer_idx) ;
1767
+ //FIXME: Do not recalculate seed values with heavy VRF operations.
1768
+ //FIXME: store block_seed into each block.
1769
+ let concatenated = [ height. to_be_bytes ( ) , view. to_be_bytes ( ) ] . concat ( ) ;
1770
+ let seed = self . signer . vrf_hash ( sha256 ( concatenated) , & mut self . vrf_inst . write ( ) ) ;
1771
+ let voting_power = 50 ;
1772
+ //FIXME: store sortition scheme.
1773
+ let sortition_scheme = VRFSortition {
1774
+ total_power : 100 ,
1775
+ expectation : 7.0 ,
1776
+ vrf_inst : Arc :: clone ( & self . vrf_inst ) ,
1777
+ } ;
1778
+ if let Ok ( true ) = message. verify ( & signer_public, voting_power, & sortition_scheme) {
1779
+ Some ( c)
1780
+ } else {
1781
+ None
1782
+ }
1783
+ } )
1784
+ }
1785
+
1731
1786
fn on_proposal_message (
1732
1787
& mut self ,
1733
1788
signature : SchnorrSignature ,
0 commit comments