@@ -22,7 +22,7 @@ use std::thread::{Builder, JoinHandle};
22
22
use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
23
23
24
24
use ccrypto:: sha256;
25
- use ckey:: { public_to_address, verify_schnorr, Address , SchnorrSignature } ;
25
+ use ckey:: { public_to_address, verify_schnorr, Address , Public , SchnorrSignature } ;
26
26
use cnetwork:: { EventSender , NodeId } ;
27
27
use crossbeam_channel as crossbeam;
28
28
use ctypes:: transaction:: { Action , Transaction } ;
@@ -32,7 +32,7 @@ use parking_lot::RwLock;
32
32
use primitives:: { u256_from_u128, Bytes , U256 } ;
33
33
use rlp:: { Encodable , Rlp } ;
34
34
use vrf:: openssl:: { CipherSuite , ECVRF } ;
35
- use vrf:: VRF ;
35
+ use vrf:: { openssl :: Error as VRFError , VRF } ;
36
36
37
37
use super :: super :: BitSet ;
38
38
use super :: backup:: { backup, restore, BackupView } ;
@@ -160,6 +160,7 @@ pub enum Event {
160
160
ProposalBlock {
161
161
signature : SchnorrSignature ,
162
162
view : View ,
163
+ priority : PriorityMessage ,
163
164
message : Bytes ,
164
165
result : crossbeam:: Sender < Option < Arc < dyn ConsensusClient > > > ,
165
166
} ,
@@ -344,22 +345,14 @@ impl Worker {
344
345
inner. restore( ) ;
345
346
result. send( ( ) ) . unwrap( ) ;
346
347
}
347
- Ok ( Event :: Priority {
348
- round,
349
- signer_idx,
350
- message,
351
- result,
352
- } ) => {
353
- inner. on_priority_message( round, signer_idx, message) ;
354
- result. send( ( ) ) . unwrap( ) ;
355
- }
356
348
Ok ( Event :: ProposalBlock {
357
349
signature,
358
350
view,
351
+ priority,
359
352
message,
360
353
result,
361
354
} ) => {
362
- let client = inner. on_proposal_message( signature, view, message) ;
355
+ let client = inner. on_proposal_message( signature, view, priority , message) ;
363
356
result. send( client) . unwrap( ) ;
364
357
}
365
358
Ok ( Event :: StepState {
@@ -435,11 +428,12 @@ impl Worker {
435
428
current_seed : & VRFSeed ,
436
429
prev_seed : & VRFSeed ,
437
430
prev_round : & SortitionRound ,
431
+ signer_pubkey : & Public ,
438
432
prev_proof : & [ u8 ] ,
439
- ) -> Result < ( ) , Error > {
433
+ ) -> Result < bool , VRFError > {
440
434
let vrf_inst = self . sortition_scheme . vrf_inst . write ( ) ;
441
- let message = [ & prev_seed[ .. ] , & prev_round. height . to_be_bytes ( ) , & prev_round. view . to_be_bytes ( ) ] . concat ( ) ;
442
- Ok ( ( ) )
435
+ let message = prev_seed. generate_next_msg ( prev_round. height , prev_round. view ) ;
436
+ vrf_inst . verify ( signer_pubkey , prev_proof , & message ) . map ( |expected_seed| expected_seed == current_seed . to_vec ( ) )
443
437
}
444
438
445
439
fn fetch_vrf_seed ( & self , block_hash : BlockHash ) -> Option < VRFSeed > {
@@ -448,6 +442,12 @@ impl Worker {
448
442
Some ( TendermintSealView :: new ( & block_seal) . vrf_seed ( ) . unwrap ( ) )
449
443
}
450
444
445
+ fn fetch_vrf_seed_proof ( & self , block_hash : BlockHash ) -> Option < Vec < u8 > > {
446
+ let block_header = self . client ( ) . block_header ( & block_hash. into ( ) ) ?;
447
+ let block_seal = block_header. seal ( ) ;
448
+ Some ( TendermintSealView :: new ( & block_seal) . vrf_seed_proof ( ) . unwrap ( ) )
449
+ }
450
+
451
451
fn prev_vrf_seed ( & self ) -> VRFSeed {
452
452
let parent_header =
453
453
self . prev_block_header_of_height ( self . height ) . expect ( "Height is increased when previous block is imported" ) ;
@@ -1260,8 +1260,7 @@ impl Worker {
1260
1260
parent_seal_view. parent_block_finalized_view ( ) . map_err ( |_| BlockError :: InvalidSeal ) ?;
1261
1261
let current_vrf_proof = current_seal_view. vrf_seed_proof ( ) . map_err ( |_| BlockError :: InvalidSeal ) ?;
1262
1262
1263
- let message =
1264
- [ & parent_vrf_seed[ ..] , & parent. number ( ) . to_be_bytes ( ) , & parent_fianlized_view. to_be_bytes ( ) ] . concat ( ) ;
1263
+ let message = parent_vrf_seed. generate_next_msg ( parent. number ( ) , parent_fianlized_view) ;
1265
1264
1266
1265
let current_vrf_seed =
1267
1266
TendermintSealView :: new ( & current_seal) . vrf_seed ( ) . map_err ( |_| BlockError :: InvalidSeal ) ?;
@@ -1843,40 +1842,15 @@ impl Worker {
1843
1842
result. send ( message. rlp_bytes ( ) . into_vec ( ) ) . unwrap ( ) ;
1844
1843
}
1845
1844
1846
- //FIXME: Log errors
1847
- fn on_priority_message ( & mut self , round : SortitionRound , signer_idx : usize , message : PriorityMessage ) {
1848
- if let Some ( c) = self . client . upgrade ( ) {
1849
- let height = round. height ;
1850
- let view = round. view ;
1851
- if let Some ( parent_hash) = c. block_hash ( & BlockId :: Number ( height - 1 ) ) {
1852
- let signer_public = self . validators . get ( & parent_hash, signer_idx) ;
1853
- //FIXME: Do not recalculate seed values with heavy VRF operations.
1854
- //FIXME: store block_seed into each block.
1855
- let concatenated = [ height. to_be_bytes ( ) , view. to_be_bytes ( ) ] . concat ( ) ;
1856
- let expected_seed =
1857
- self . signer . vrf_hash ( sha256 ( concatenated) , & mut self . sortition_scheme . vrf_inst . write ( ) ) ;
1858
- //FIXME: Handle errors
1859
- let voting_power = self
1860
- . validators
1861
- . normalized_voting_power ( & parent_hash, signer_idx, self . sortition_scheme . total_power )
1862
- . unwrap ( ) ;
1863
- match expected_seed. map ( |seed| seed == message. seed . to_vec ( ) ) {
1864
- Ok ( true ) => match message. verify ( & signer_public, voting_power, & self . sortition_scheme ) {
1865
- Ok ( true ) => { }
1866
- _ => return ,
1867
- } ,
1868
- _ => return ,
1869
- } ;
1870
-
1871
- self . sortition_infos . insert ( & message, signer_idx, round) ;
1872
- }
1873
- }
1845
+ fn get_voting_power ( & self , block_hash : & BlockHash , signer_idx : usize ) -> u64 {
1846
+ self . validators . normalized_voting_power ( block_hash, signer_idx, self . sortition_scheme . total_power ) . unwrap ( )
1874
1847
}
1875
1848
1876
1849
fn on_proposal_message (
1877
1850
& mut self ,
1878
1851
signature : SchnorrSignature ,
1879
1852
proposed_view : View ,
1853
+ priority : PriorityMessage ,
1880
1854
bytes : Bytes ,
1881
1855
) -> Option < Arc < dyn ConsensusClient > > {
1882
1856
let c = self . client . upgrade ( ) ?;
@@ -1935,6 +1909,33 @@ impl Worker {
1935
1909
_ => { }
1936
1910
}
1937
1911
1912
+ // priority verification block
1913
+ {
1914
+ if let ( Some ( parent_seed) , Some ( parent_seed_proof) ) =
1915
+ ( self . fetch_vrf_seed ( * parent_hash) , self . fetch_vrf_seed_proof ( * parent_hash) )
1916
+ {
1917
+ self . verify_vrf_seed (
1918
+ & priority. seed ( ) ,
1919
+ & parent_seed,
1920
+ & SortitionRound {
1921
+ height : self . height - 1 ,
1922
+ view : self . finalized_view_of_previous_block ,
1923
+ } ,
1924
+ & signer_public,
1925
+ & parent_seed_proof,
1926
+ ) ;
1927
+
1928
+ let voting_power = self . get_voting_power ( & parent_hash, message. signer_index ( ) ) ;
1929
+ match priority. verify ( & signer_public, voting_power, & self . sortition_scheme ) {
1930
+ Ok ( true ) => { }
1931
+ _ => {
1932
+ cwarn ! ( ENGINE , "Proposal verification failed" ) ;
1933
+ return None
1934
+ }
1935
+ }
1936
+ }
1937
+ }
1938
+
1938
1939
if self . votes . is_old_or_known ( & message) {
1939
1940
cdebug ! ( ENGINE , "Proposal is already known" ) ;
1940
1941
return None
0 commit comments