@@ -32,11 +32,13 @@ use sc_network_gossip::GossipEngine;
32
32
33
33
use sp_api:: BlockId ;
34
34
use sp_application_crypto:: { AppPublic , Public } ;
35
+ use sp_arithmetic:: traits:: AtLeast32Bit ;
35
36
use sp_core:: Pair ;
36
37
use sp_keystore:: { SyncCryptoStore , SyncCryptoStorePtr } ;
37
38
use sp_runtime:: {
38
39
generic:: OpaqueDigestItemId ,
39
- traits:: { Block , Header , NumberFor , Zero } ,
40
+ traits:: { Block , Header , NumberFor } ,
41
+ SaturatedConversion ,
40
42
} ;
41
43
42
44
use beefy_primitives:: {
76
78
best_grandpa_block : NumberFor < B > ,
77
79
/// Best block a BEEFY voting round has been concluded for
78
80
best_beefy_block : Option < NumberFor < B > > ,
79
- /// Best block this node has voted for
80
- best_block_voted_on : NumberFor < B > ,
81
81
/// Validator set id for the last signed commitment
82
82
last_signed_id : u64 ,
83
83
// keep rustc happy
@@ -122,7 +122,6 @@ where
122
122
finality_notifications : client. finality_notification_stream ( ) ,
123
123
best_grandpa_block : client. info ( ) . finalized_number ,
124
124
best_beefy_block : None ,
125
- best_block_voted_on : Zero :: zero ( ) ,
126
125
last_signed_id : 0 ,
127
126
_backend : PhantomData ,
128
127
_pair : PhantomData ,
@@ -142,32 +141,20 @@ where
142
141
{
143
142
/// Return `true`, if we should vote on block `number`
144
143
fn should_vote_on ( & self , number : NumberFor < B > ) -> bool {
145
- use sp_runtime:: { traits:: Saturating , SaturatedConversion } ;
146
-
147
144
let best_beefy_block = if let Some ( block) = self . best_beefy_block {
148
145
block
149
146
} else {
150
147
debug ! ( target: "beefy" , "🥩 Missing best BEEFY block - won't vote for: {:?}" , number) ;
151
148
return false ;
152
149
} ;
153
150
154
- let diff = self . best_grandpa_block . saturating_sub ( best_beefy_block) ;
155
- let diff = diff. saturated_into :: < u32 > ( ) ;
156
- let next_power_of_two = ( diff / 2 ) . next_power_of_two ( ) ;
157
- let next_block_to_vote_on = self . best_block_voted_on + self . min_block_delta . max ( next_power_of_two) . into ( ) ;
151
+ let target = vote_target ( self . best_grandpa_block , best_beefy_block, self . min_block_delta ) ;
158
152
159
- trace ! (
160
- target: "beefy" ,
161
- "should_vote_on: #{:?}, diff: {:?}, next_power_of_two: {:?}, next_block_to_vote_on: #{:?}" ,
162
- number,
163
- diff,
164
- next_power_of_two,
165
- next_block_to_vote_on,
166
- ) ;
153
+ trace ! ( target: "beefy" , "🥩 should_vote_on: #{:?}, next_block_to_vote_on: #{:?}" , number, target) ;
167
154
168
- metric_set ! ( self , beefy_should_vote_on, next_block_to_vote_on ) ;
155
+ metric_set ! ( self , beefy_should_vote_on, target ) ;
169
156
170
- number == next_block_to_vote_on
157
+ number == target
171
158
}
172
159
173
160
fn sign_commitment ( & self , id : & P :: Public , commitment : & [ u8 ] ) -> Result < P :: Signature , error:: Crypto < P :: Public > > {
@@ -274,8 +261,6 @@ where
274
261
}
275
262
} ;
276
263
277
- self . best_block_voted_on = * notification. header . number ( ) ;
278
-
279
264
let message = VoteMessage {
280
265
commitment,
281
266
id : local_id,
@@ -402,3 +387,116 @@ where
402
387
403
388
header. digest ( ) . convert_first ( |l| l. try_to ( id) . and_then ( filter) )
404
389
}
390
+
391
+ /// Calculate next block number to vote on
392
+ fn vote_target < N > ( best_grandpa : N , best_beefy : N , min_delta : u32 ) -> N
393
+ where
394
+ N : AtLeast32Bit + Copy + Debug ,
395
+ {
396
+ let diff = best_grandpa. saturating_sub ( best_beefy) ;
397
+ let diff = diff. saturated_into :: < u32 > ( ) ;
398
+ let target = best_beefy + min_delta. max ( diff. next_power_of_two ( ) ) . into ( ) ;
399
+
400
+ trace ! (
401
+ target: "beefy" ,
402
+ "🥩 vote target - diff: {:?}, next_power_of_two: {:?}, target block: #{:?}" ,
403
+ diff,
404
+ diff. next_power_of_two( ) ,
405
+ target,
406
+ ) ;
407
+
408
+ target
409
+ }
410
+
411
+ #[ cfg( test) ]
412
+ mod tests {
413
+ use super :: vote_target;
414
+
415
+ #[ test]
416
+ fn vote_on_min_block_delta ( ) {
417
+ let t = vote_target ( 1u32 , 0 , 4 ) ;
418
+ assert_eq ! ( 4 , t) ;
419
+ let t = vote_target ( 2u32 , 0 , 4 ) ;
420
+ assert_eq ! ( 4 , t) ;
421
+ let t = vote_target ( 3u32 , 0 , 4 ) ;
422
+ assert_eq ! ( 4 , t) ;
423
+ let t = vote_target ( 4u32 , 0 , 4 ) ;
424
+ assert_eq ! ( 4 , t) ;
425
+
426
+ let t = vote_target ( 4u32 , 4 , 4 ) ;
427
+ assert_eq ! ( 8 , t) ;
428
+
429
+ let t = vote_target ( 10u32 , 10 , 4 ) ;
430
+ assert_eq ! ( 14 , t) ;
431
+ let t = vote_target ( 11u32 , 10 , 4 ) ;
432
+ assert_eq ! ( 14 , t) ;
433
+ let t = vote_target ( 12u32 , 10 , 4 ) ;
434
+ assert_eq ! ( 14 , t) ;
435
+ let t = vote_target ( 13u32 , 10 , 4 ) ;
436
+ assert_eq ! ( 14 , t) ;
437
+
438
+ let t = vote_target ( 10u32 , 10 , 8 ) ;
439
+ assert_eq ! ( 18 , t) ;
440
+ let t = vote_target ( 11u32 , 10 , 8 ) ;
441
+ assert_eq ! ( 18 , t) ;
442
+ let t = vote_target ( 12u32 , 10 , 8 ) ;
443
+ assert_eq ! ( 18 , t) ;
444
+ let t = vote_target ( 13u32 , 10 , 8 ) ;
445
+ assert_eq ! ( 18 , t) ;
446
+ }
447
+
448
+ #[ test]
449
+ fn vote_on_power_of_two ( ) {
450
+ let t = vote_target ( 1008u32 , 1000 , 4 ) ;
451
+ assert_eq ! ( 1008 , t) ;
452
+
453
+ let t = vote_target ( 1016u32 , 1000 , 4 ) ;
454
+ assert_eq ! ( 1016 , t) ;
455
+
456
+ let t = vote_target ( 1032u32 , 1000 , 4 ) ;
457
+ assert_eq ! ( 1032 , t) ;
458
+
459
+ let t = vote_target ( 1064u32 , 1000 , 4 ) ;
460
+ assert_eq ! ( 1064 , t) ;
461
+
462
+ let t = vote_target ( 1128u32 , 1000 , 4 ) ;
463
+ assert_eq ! ( 1128 , t) ;
464
+
465
+ let t = vote_target ( 1256u32 , 1000 , 4 ) ;
466
+ assert_eq ! ( 1256 , t) ;
467
+
468
+ let t = vote_target ( 1512u32 , 1000 , 4 ) ;
469
+ assert_eq ! ( 1512 , t) ;
470
+
471
+ let t = vote_target ( 1024u32 , 0 , 4 ) ;
472
+ assert_eq ! ( 1024 , t) ;
473
+ }
474
+
475
+ #[ test]
476
+ fn vote_on_target_block ( ) {
477
+ let t = vote_target ( 1008u32 , 1002 , 4 ) ;
478
+ assert_eq ! ( 1010 , t) ;
479
+ let t = vote_target ( 1010u32 , 1002 , 4 ) ;
480
+ assert_eq ! ( 1010 , t) ;
481
+
482
+ let t = vote_target ( 1016u32 , 1006 , 4 ) ;
483
+ assert_eq ! ( 1022 , t) ;
484
+ let t = vote_target ( 1022u32 , 1006 , 4 ) ;
485
+ assert_eq ! ( 1022 , t) ;
486
+
487
+ let t = vote_target ( 1032u32 , 1012 , 4 ) ;
488
+ assert_eq ! ( 1044 , t) ;
489
+ let t = vote_target ( 1044u32 , 1012 , 4 ) ;
490
+ assert_eq ! ( 1044 , t) ;
491
+
492
+ let t = vote_target ( 1064u32 , 1014 , 4 ) ;
493
+ assert_eq ! ( 1078 , t) ;
494
+ let t = vote_target ( 1078u32 , 1014 , 4 ) ;
495
+ assert_eq ! ( 1078 , t) ;
496
+
497
+ let t = vote_target ( 1128u32 , 1008 , 4 ) ;
498
+ assert_eq ! ( 1136 , t) ;
499
+ let t = vote_target ( 1136u32 , 1008 , 4 ) ;
500
+ assert_eq ! ( 1136 , t) ;
501
+ }
502
+ }
0 commit comments