@@ -26,7 +26,7 @@ use witnet_data_structures::{
26
26
} ,
27
27
error:: { BlockError , DataRequestError , TransactionError } ,
28
28
get_environment,
29
- mainnet_validations:: { after_first_hard_fork, after_second_hard_fork} ,
29
+ mainnet_validations:: { after_first_hard_fork, after_second_hard_fork, after_third_hard_fork } ,
30
30
radon_error:: RadonError ,
31
31
radon_report:: { RadonReport , ReportContext , Stage , TallyMetaData } ,
32
32
transaction:: {
@@ -916,7 +916,15 @@ pub fn validate_commit_transaction(
916
916
let pkh = proof_pkh;
917
917
let backup_witnesses = dr_state. backup_witnesses ( ) ;
918
918
let num_witnesses = dr_output. witnesses + backup_witnesses;
919
- let ( target_hash, _) = calculate_reppoe_threshold ( rep_eng, & pkh, num_witnesses) ;
919
+ // TODO: pass difficulty as an argument to this function (from consensus constants)
920
+ let minimum_reppoe_difficulty = 2000 ;
921
+ let ( target_hash, _) = calculate_reppoe_threshold (
922
+ rep_eng,
923
+ & pkh,
924
+ num_witnesses,
925
+ epoch,
926
+ minimum_reppoe_difficulty,
927
+ ) ;
920
928
add_dr_vrf_signature_to_verify (
921
929
signatures_to_verify,
922
930
& co_tx. body . proof ,
@@ -1548,6 +1556,7 @@ struct WitnessesCount {
1548
1556
current : u32 ,
1549
1557
target : u32 ,
1550
1558
}
1559
+
1551
1560
type WitnessesCounter < S > = HashMap < Hash , WitnessesCount , S > ;
1552
1561
1553
1562
// Add 1 in the number assigned to a OutputPointer
@@ -2091,20 +2100,31 @@ pub fn calculate_reppoe_threshold(
2091
2100
rep_eng : & ReputationEngine ,
2092
2101
pkh : & PublicKeyHash ,
2093
2102
num_witnesses : u16 ,
2103
+ block_epoch : u32 ,
2104
+ minimum_difficulty : u32 ,
2094
2105
) -> ( Hash , f64 ) {
2095
- let total_active_rep = rep_eng. total_active_reputation ( ) ;
2096
-
2097
2106
// Add 1 to reputation because otherwise a node with 0 reputation would
2098
2107
// never be eligible for a data request
2099
- let my_reputation = u64:: from ( rep_eng. get_eligibility ( pkh) ) + 1 ;
2108
+ let my_eligibility = u64:: from ( rep_eng. get_eligibility ( pkh) ) + 1 ;
2100
2109
let factor = u64:: from ( rep_eng. threshold_factor ( num_witnesses) ) ;
2101
2110
2102
2111
let max = u64:: max_value ( ) ;
2103
- // Check for overflow: when the probability is more than 100%, cap it to 100%
2104
- let target = if my_reputation. saturating_mul ( factor) >= total_active_rep {
2105
- max
2112
+ // Compute target eligibility and hard-cap it if required
2113
+ let target = if after_third_hard_fork ( block_epoch, get_environment ( ) ) {
2114
+ // TODO: Review if next line is required (check if total active reputation could be zero)
2115
+ let total_active_rep = std:: cmp:: max ( rep_eng. total_active_reputation ( ) , 1 ) ;
2116
+ // If eligibility is more than 100%, cap it to (max/minimum_difficulty*factor)%
2117
+ std:: cmp:: min (
2118
+ max / u64:: from ( minimum_difficulty) ,
2119
+ ( max / total_active_rep) . saturating_mul ( my_eligibility) ,
2120
+ )
2121
+ . saturating_mul ( factor)
2106
2122
} else {
2107
- ( max / total_active_rep) * my_reputation. saturating_mul ( factor)
2123
+ // Check for overflow: when the probability is more than 100%, cap it to 100%
2124
+ let total_active_rep = rep_eng. total_active_reputation ( ) ;
2125
+ ( max / total_active_rep)
2126
+ . saturating_mul ( my_eligibility)
2127
+ . saturating_mul ( factor)
2108
2128
} ;
2109
2129
let target = u32:: try_from ( target >> 32 ) . unwrap ( ) ;
2110
2130
@@ -2222,7 +2242,8 @@ pub fn validate_merkle_tree(block: &Block) -> bool {
2222
2242
2223
2243
/// 1 nanowit is the minimal unit of value
2224
2244
/// 1 wit = 10^9 nanowits
2225
- pub const NANOWITS_PER_WIT : u64 = 1_000_000_000 ; // 10 ^ WIT_DECIMAL_PLACES
2245
+ pub const NANOWITS_PER_WIT : u64 = 1_000_000_000 ;
2246
+ // 10 ^ WIT_DECIMAL_PLACES
2226
2247
/// Number of decimal places used in the string representation of wit value.
2227
2248
pub const WIT_DECIMAL_PLACES : u8 = 9 ;
2228
2249
@@ -2482,7 +2503,7 @@ mod tests {
2482
2503
rep_2,
2483
2504
vrf_j,
2484
2505
act_j,
2485
- & vrf_sections
2506
+ & vrf_sections,
2486
2507
) ,
2487
2508
Ordering :: Less
2488
2509
) ;
@@ -2496,7 +2517,7 @@ mod tests {
2496
2517
rep_1,
2497
2518
vrf_j,
2498
2519
act_j,
2499
- & vrf_sections
2520
+ & vrf_sections,
2500
2521
) ,
2501
2522
Ordering :: Greater
2502
2523
) ;
@@ -2522,7 +2543,7 @@ mod tests {
2522
2543
rep_1,
2523
2544
vrf_j,
2524
2545
false ,
2525
- & vrf_sections
2546
+ & vrf_sections,
2526
2547
) ,
2527
2548
Ordering :: Greater
2528
2549
) ;
@@ -2536,7 +2557,7 @@ mod tests {
2536
2557
rep_2,
2537
2558
vrf_j,
2538
2559
true ,
2539
- & vrf_sections
2560
+ & vrf_sections,
2540
2561
) ,
2541
2562
Ordering :: Less
2542
2563
) ;
@@ -2558,7 +2579,7 @@ mod tests {
2558
2579
rep_1,
2559
2580
vrf_2,
2560
2581
true ,
2561
- & vrf_sections
2582
+ & vrf_sections,
2562
2583
) ,
2563
2584
Ordering :: Greater
2564
2585
) ;
@@ -2572,7 +2593,7 @@ mod tests {
2572
2593
rep_1,
2573
2594
vrf_1,
2574
2595
true ,
2575
- & vrf_sections
2596
+ & vrf_sections,
2576
2597
) ,
2577
2598
Ordering :: Less
2578
2599
) ;
@@ -2590,7 +2611,7 @@ mod tests {
2590
2611
rep_1,
2591
2612
vrf_1,
2592
2613
true ,
2593
- & vrf_sections
2614
+ & vrf_sections,
2594
2615
) ,
2595
2616
Ordering :: Greater
2596
2617
) ;
@@ -2604,7 +2625,7 @@ mod tests {
2604
2625
rep_1,
2605
2626
vrf_1,
2606
2627
true ,
2607
- & vrf_sections
2628
+ & vrf_sections,
2608
2629
) ,
2609
2630
Ordering :: Less
2610
2631
) ;
@@ -2620,7 +2641,7 @@ mod tests {
2620
2641
rep_1,
2621
2642
vrf_1,
2622
2643
true ,
2623
- & vrf_sections
2644
+ & vrf_sections,
2624
2645
) ,
2625
2646
Ordering :: Equal
2626
2647
) ;
@@ -2656,7 +2677,7 @@ mod tests {
2656
2677
rep_j,
2657
2678
vrf_2,
2658
2679
act_j,
2659
- & vrf_sections
2680
+ & vrf_sections,
2660
2681
) ,
2661
2682
Ordering :: Greater
2662
2683
) ;
@@ -2670,7 +2691,7 @@ mod tests {
2670
2691
rep_j,
2671
2692
vrf_1,
2672
2693
act_j,
2673
- & vrf_sections
2694
+ & vrf_sections,
2674
2695
) ,
2675
2696
Ordering :: Less
2676
2697
) ;
@@ -2704,7 +2725,7 @@ mod tests {
2704
2725
rep_2,
2705
2726
vrf_2,
2706
2727
true ,
2707
- & vrf_sections
2728
+ & vrf_sections,
2708
2729
) ,
2709
2730
Ordering :: Greater
2710
2731
) ;
@@ -2719,7 +2740,7 @@ mod tests {
2719
2740
rep_2,
2720
2741
vrf_1,
2721
2742
true ,
2722
- & vrf_sections
2743
+ & vrf_sections,
2723
2744
) ,
2724
2745
Ordering :: Less
2725
2746
) ;
@@ -2950,7 +2971,7 @@ mod tests {
2950
2971
rep_engine. ars_mut ( ) . push_activity ( vec ! [ id1] ) ;
2951
2972
2952
2973
// 100% when we have all the reputation
2953
- let ( t00, p00) = calculate_reppoe_threshold ( & rep_engine, & id1, 1 ) ;
2974
+ let ( t00, p00) = calculate_reppoe_threshold ( & rep_engine, & id1, 1 , 0 , 2000 ) ;
2954
2975
assert_eq ! ( t00, Hash :: with_first_u32( 0xFFFF_FFFF ) ) ;
2955
2976
assert_eq ! ( ( p00 * 100_f64 ) . round( ) as i128 , 100 ) ;
2956
2977
@@ -2962,7 +2983,7 @@ mod tests {
2962
2983
rep_engine. ars_mut ( ) . push_activity ( vec ! [ id2] ) ;
2963
2984
2964
2985
// 50% when there are 2 nodes with 50% of the reputation each
2965
- let ( t01, p01) = calculate_reppoe_threshold ( & rep_engine, & id1, 1 ) ;
2986
+ let ( t01, p01) = calculate_reppoe_threshold ( & rep_engine, & id1, 1 , 0 , 2000 ) ;
2966
2987
// Since the calculate_reppoe function first divides and later
2967
2988
// multiplies, we get a rounding error here
2968
2989
assert_eq ! ( t01, Hash :: with_first_u32( 0x7FFF_FFFF ) ) ;
@@ -3003,7 +3024,8 @@ mod tests {
3003
3024
let mut v = vec ! [ ] ;
3004
3025
for id in ids. iter ( ) {
3005
3026
v. push (
3006
- ( calculate_reppoe_threshold ( & rep_engine, id, thres) . 1 * 100_f64 ) . round ( ) as u32 ,
3027
+ ( calculate_reppoe_threshold ( & rep_engine, id, thres, 0 , 2000 ) . 1 * 100_f64 )
3028
+ . round ( ) as u32 ,
3007
3029
) ;
3008
3030
}
3009
3031
v
@@ -3034,16 +3056,16 @@ mod tests {
3034
3056
let id0 = PublicKeyHash :: from_bytes ( & [ 0 ; 20 ] ) . unwrap ( ) ;
3035
3057
3036
3058
// 100% when the total reputation is 0
3037
- let ( t00, p00) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 ) ;
3038
- assert_eq ! ( t00, Hash :: with_first_u32( 0xFFFF_FFFF ) ) ;
3059
+ let ( t00, p00) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 , 0 , 2000 ) ;
3039
3060
assert_eq ! ( ( p00 * 100_f64 ) . round( ) as i128 , 100 ) ;
3040
- let ( t01, p01) = calculate_reppoe_threshold ( & rep_engine, & id0, 100 ) ;
3061
+ assert_eq ! ( t00, Hash :: with_first_u32( 0xFFFF_FFFF ) ) ;
3062
+ let ( t01, p01) = calculate_reppoe_threshold ( & rep_engine, & id0, 100 , 0 , 2000 ) ;
3041
3063
assert_eq ! ( t01, Hash :: with_first_u32( 0xFFFF_FFFF ) ) ;
3042
3064
assert_eq ! ( ( p01 * 100_f64 ) . round( ) as i128 , 100 ) ;
3043
3065
3044
3066
let id1 = PublicKeyHash :: from_bytes ( & [ 1 ; 20 ] ) . unwrap ( ) ;
3045
3067
rep_engine. ars_mut ( ) . push_activity ( vec ! [ id1] ) ;
3046
- let ( t02, p02) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 ) ;
3068
+ let ( t02, p02) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 , 0 , 2000 ) ;
3047
3069
assert_eq ! ( t02, Hash :: with_first_u32( 0xFFFF_FFFF ) ) ;
3048
3070
assert_eq ! ( ( p02 * 100_f64 ) . round( ) as i128 , 100 ) ;
3049
3071
@@ -3052,14 +3074,14 @@ mod tests {
3052
3074
. trs_mut ( )
3053
3075
. gain ( Alpha ( 10 ) , vec ! [ ( id1, Reputation ( 1 ) ) ] )
3054
3076
. unwrap ( ) ;
3055
- let ( t03, p03) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 ) ;
3077
+ let ( t03, p03) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 , 0 , 2000 ) ;
3056
3078
assert_eq ! ( t03, Hash :: with_first_u32( 0x7FFF_FFFF ) ) ;
3057
3079
assert_eq ! ( ( p03 * 100_f64 ) . round( ) as i128 , 50 ) ;
3058
3080
3059
3081
// 33% when the total reputation is 1 but there are 2 active identities
3060
3082
let id2 = PublicKeyHash :: from_bytes ( & [ 2 ; 20 ] ) . unwrap ( ) ;
3061
3083
rep_engine. ars_mut ( ) . push_activity ( vec ! [ id2] ) ;
3062
- let ( t04, p04) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 ) ;
3084
+ let ( t04, p04) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 , 0 , 2000 ) ;
3063
3085
assert_eq ! ( t04, Hash :: with_first_u32( 0x5555_5555 ) ) ;
3064
3086
assert_eq ! ( ( p04 * 100_f64 ) . round( ) as i128 , 33 ) ;
3065
3087
@@ -3073,7 +3095,7 @@ mod tests {
3073
3095
. trs_mut ( )
3074
3096
. gain ( Alpha ( 10 ) , vec ! [ ( id1, Reputation ( 99 ) ) ] )
3075
3097
. unwrap ( ) ;
3076
- let ( t05, p05) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 ) ;
3098
+ let ( t05, p05) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 , 0 , 2000 ) ;
3077
3099
assert_eq ! ( t05, Hash :: with_first_u32( 0x0253_C825 ) ) ;
3078
3100
assert_eq ! ( ( p05 * 100_f64 ) . round( ) as i128 , 1 ) ;
3079
3101
}
@@ -3094,7 +3116,7 @@ mod tests {
3094
3116
. unwrap ( ) ;
3095
3117
3096
3118
// Test big values that result in < 100%
3097
- let ( t01, p01) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 ) ;
3119
+ let ( t01, p01) = calculate_reppoe_threshold ( & rep_engine, & id0, 1 , 0 , 2000 ) ;
3098
3120
assert_eq ! ( t01, Hash :: with_first_u32( 0xFFFF_FFFE ) ) ;
3099
3121
assert_eq ! ( ( p01 * 100_f64 ) . round( ) as i128 , 100 ) ;
3100
3122
}
@@ -3388,7 +3410,7 @@ mod tests {
3388
3410
out,
3389
3411
RadError :: InsufficientConsensus {
3390
3412
achieved: 0.5 ,
3391
- required: 0.51
3413
+ required: 0.51 ,
3392
3414
}
3393
3415
) ;
3394
3416
}
@@ -3415,7 +3437,7 @@ mod tests {
3415
3437
out,
3416
3438
RadError :: InsufficientConsensus {
3417
3439
achieved: 0.5 ,
3418
- required: 0.51
3440
+ required: 0.51 ,
3419
3441
}
3420
3442
) ;
3421
3443
}
0 commit comments