@@ -15,7 +15,7 @@ use near_primitives::types::{
1515 AccountId , ApprovalStake , Balance , BlockChunkValidatorStats , BlockHeight , EpochId , ShardId ,
1616 ValidatorId , ValidatorKickoutReason , ValidatorStake , ValidatorStats ,
1717} ;
18- use near_primitives:: version:: ProtocolVersion ;
18+ use near_primitives:: version:: { ProtocolVersion , UPGRADABILITY_FIX_PROTOCOL_VERSION } ;
1919use near_primitives:: views:: {
2020 CurrentEpochValidatorInfo , EpochValidatorInfo , NextEpochValidatorInfo , ValidatorKickoutView ,
2121} ;
@@ -236,6 +236,13 @@ impl EpochManager {
236236 . map ( |& id| epoch_info. validators [ * id as usize ] . stake )
237237 . sum ( ) ;
238238
239+ let protocol_version = if epoch_info. protocol_version >= UPGRADABILITY_FIX_PROTOCOL_VERSION
240+ {
241+ next_epoch_info. protocol_version
242+ } else {
243+ epoch_info. protocol_version
244+ } ;
245+
239246 let next_version = if let Some ( ( & version, stake) ) =
240247 versions. into_iter ( ) . max_by ( |left, right| left. 1 . cmp ( & right. 1 ) )
241248 {
@@ -246,10 +253,10 @@ impl EpochManager {
246253 {
247254 version
248255 } else {
249- epoch_info . protocol_version
256+ protocol_version
250257 }
251258 } else {
252- epoch_info . protocol_version
259+ protocol_version
253260 } ;
254261
255262 // Gather slashed validators and add them to kick out first.
@@ -2981,4 +2988,68 @@ mod tests {
29812988 PROTOCOL_VERSION
29822989 ) ;
29832990 }
2991+
2992+ #[ test]
2993+ fn test_protocol_version_switch_after_switch ( ) {
2994+ let store = create_test_store ( ) ;
2995+ let config = epoch_config ( 2 , 1 , 2 , 0 , 90 , 60 , 0 ) ;
2996+ let amount_staked = 1_000_000 ;
2997+ let validators = vec ! [ stake( "test1" , amount_staked) , stake( "test2" , amount_staked) ] ;
2998+ let mut epoch_manager = EpochManager :: new (
2999+ store. clone ( ) ,
3000+ config. clone ( ) ,
3001+ UPGRADABILITY_FIX_PROTOCOL_VERSION ,
3002+ default_reward_calculator ( ) ,
3003+ validators. clone ( ) ,
3004+ )
3005+ . unwrap ( ) ;
3006+ let h = hash_range ( 10 ) ;
3007+ record_block ( & mut epoch_manager, CryptoHash :: default ( ) , h[ 0 ] , 0 , vec ! [ ] ) ;
3008+ for i in 1 ..5 {
3009+ let mut block_info = block_info (
3010+ i as u64 ,
3011+ i as u64 - 1 ,
3012+ h[ i - 1 ] ,
3013+ h[ i - 1 ] ,
3014+ h[ 0 ] ,
3015+ vec ! [ ] ,
3016+ DEFAULT_TOTAL_SUPPLY ,
3017+ ) ;
3018+ if i != 4 {
3019+ block_info. latest_protocol_version = UPGRADABILITY_FIX_PROTOCOL_VERSION + 1 ;
3020+ } else {
3021+ block_info. latest_protocol_version = UPGRADABILITY_FIX_PROTOCOL_VERSION ;
3022+ }
3023+ epoch_manager. record_block_info ( & h[ i] , block_info, [ 0 ; 32 ] ) . unwrap ( ) ;
3024+ }
3025+
3026+ assert_eq ! (
3027+ epoch_manager. get_epoch_info( & EpochId ( h[ 2 ] ) ) . unwrap( ) . protocol_version,
3028+ UPGRADABILITY_FIX_PROTOCOL_VERSION + 1
3029+ ) ;
3030+
3031+ assert_eq ! (
3032+ epoch_manager. get_epoch_info( & EpochId ( h[ 4 ] ) ) . unwrap( ) . protocol_version,
3033+ UPGRADABILITY_FIX_PROTOCOL_VERSION + 1
3034+ ) ;
3035+
3036+ // if there are enough votes to use the old version, it should be allowed
3037+ for i in 5 ..7 {
3038+ let mut block_info = block_info (
3039+ i as u64 ,
3040+ i as u64 - 1 ,
3041+ h[ i - 1 ] ,
3042+ h[ i - 1 ] ,
3043+ h[ 0 ] ,
3044+ vec ! [ ] ,
3045+ DEFAULT_TOTAL_SUPPLY ,
3046+ ) ;
3047+ block_info. latest_protocol_version = UPGRADABILITY_FIX_PROTOCOL_VERSION ;
3048+ epoch_manager. record_block_info ( & h[ i] , block_info, [ 0 ; 32 ] ) . unwrap ( ) ;
3049+ }
3050+ assert_eq ! (
3051+ epoch_manager. get_epoch_info( & EpochId ( h[ 6 ] ) ) . unwrap( ) . protocol_version,
3052+ UPGRADABILITY_FIX_PROTOCOL_VERSION
3053+ ) ;
3054+ }
29843055}
0 commit comments