Skip to content

Commit 756e0fc

Browse files
committed
update interpolate. change lpf
1 parent 3788e27 commit 756e0fc

File tree

4 files changed

+39
-11219
lines changed

4 files changed

+39
-11219
lines changed

gossip/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ pub mod epoch_slots;
3131
pub mod epoch_specs;
3232
pub mod gossip_error;
3333
pub mod gossip_service;
34-
pub mod low_pass_filter;
3534
pub mod node;
3635
#[macro_use]
3736
mod tlv;

gossip/src/push_active_set.rs

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ impl From<&WeightingConfig> for WeightingMode {
5757
fn get_weight(bucket: u64, alpha: u64) -> u64 {
5858
debug_assert!((ALPHA_MIN..=ALPHA_MIN + lpf::SCALE.get()).contains(&alpha));
5959
let b = bucket + 1;
60-
linearly_interpolate(b, alpha)
60+
let b_squared = b.saturating_mul(b);
61+
gossip_interpolate_weight(b, b_squared, alpha)
6162
}
6263

6364
/// Approximates `base^alpha` rounded to nearest integer using
@@ -66,11 +67,10 @@ fn get_weight(bucket: u64, alpha: u64) -> u64 {
6667
/// Note: This function is most accurate when `base` is small e.g. < ~25.
6768
#[inline]
6869
#[allow(clippy::arithmetic_side_effects)]
69-
pub fn linearly_interpolate(base: u64, alpha: u64) -> u64 {
70+
pub fn gossip_interpolate_weight(base: u64, base_squared: u64, alpha: u64) -> u64 {
7071
let scale = lpf::SCALE.get();
7172
let t = alpha.saturating_sub(ALPHA_MIN);
7273
debug_assert!(t <= scale, "interpolation t={} > SCALE={}", t, scale);
73-
let base_squared = base.saturating_mul(base);
7474
// ((base * (scale - t) + base_squared * t) + scale / 2) / scale
7575
((base.saturating_mul(scale.saturating_sub(t))).saturating_add(base_squared.saturating_mul(t)))
7676
.saturating_add(scale / 2)
@@ -922,21 +922,24 @@ mod tests {
922922

923923
#[test]
924924
fn test_interpolate_t_zero() {
925-
// When t=0, should return base
926-
assert_eq!(linearly_interpolate(100, 0), 100);
927-
assert_eq!(linearly_interpolate(0, 0), 0);
928-
assert_eq!(linearly_interpolate(1000000, 0), 1000000);
925+
// When alpha = ALPHA_MIN (t = 0), should return base
926+
assert_eq!(gossip_interpolate_weight(100, 100 * 100, ALPHA_MIN), 100);
927+
assert_eq!(gossip_interpolate_weight(0, 0, ALPHA_MIN), 0);
928+
assert_eq!(
929+
gossip_interpolate_weight(1_000_000, 1_000_000 * 1_000_000, ALPHA_MIN),
930+
1_000_000
931+
);
929932
}
930933

931934
#[test]
932935
fn test_interpolate_t_max() {
933-
// When t=SCALE, should return base^2
936+
// When alpha = ALPHA_MAX (t = SCALE), should return base^2
934937
let base = 100;
935-
let result = linearly_interpolate(base, lpf::SCALE.get());
938+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MAX);
936939
assert_eq!(result, base * base);
937940

938941
let base2 = 1000;
939-
let result = linearly_interpolate(base2, lpf::SCALE.get());
942+
let result = gossip_interpolate_weight(base2, base2 * base2, ALPHA_MAX);
940943
assert_eq!(result, base2 * base2);
941944
}
942945

@@ -947,62 +950,68 @@ mod tests {
947950
let t_75 = lpf::SCALE.get() * 3 / 4; // 75%
948951

949952
let base = 3;
950-
let result = linearly_interpolate(base, t_10);
953+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_10);
951954
assert_eq!(result, 4);
952955

953-
let result = linearly_interpolate(base, t_50);
956+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_50);
954957
assert_eq!(result, 6);
955958

956-
let result = linearly_interpolate(base, t_75);
959+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_75);
957960
assert_eq!(result, 8);
958961

959962
let base = 15;
960-
let result = linearly_interpolate(base, t_10);
963+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_10);
961964
assert_eq!(result, 36);
962965

963-
let result = linearly_interpolate(base, t_50);
966+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_50);
964967
assert_eq!(result, 120);
965968

966-
let result = linearly_interpolate(base, t_75);
969+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_75);
967970
assert_eq!(result, 173);
968971

969972
let base = 24;
970-
let result = linearly_interpolate(base, t_10);
973+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_10);
971974
assert_eq!(result, 79);
972975

973-
let result = linearly_interpolate(base, t_50);
976+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_50);
974977
assert_eq!(result, 300);
975978

976-
let result = linearly_interpolate(base, t_75);
979+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t_75);
977980
assert_eq!(result, 438);
978981
}
979982

980983
#[test]
981984
fn test_interpolate_large_base() {
982-
let base = 1000000000;
983-
let result = linearly_interpolate(base, lpf::SCALE.get() / 2);
985+
let base = 1_000_000_000u64;
986+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + lpf::SCALE.get() / 2);
984987
assert!(result >= base);
985988
assert!(result < base * base);
986989
}
987990

988991
#[test]
989992
fn test_interpolate_edge_cases() {
990993
// Test with base = 1
991-
assert_eq!(linearly_interpolate(1, 0), 1);
992-
assert_eq!(linearly_interpolate(1, lpf::SCALE.get()), 1);
993-
assert_eq!(linearly_interpolate(1, lpf::SCALE.get() / 2), 1);
994+
assert_eq!(gossip_interpolate_weight(1, 1, ALPHA_MIN), 1);
995+
assert_eq!(gossip_interpolate_weight(1, 1, ALPHA_MAX), 1);
996+
assert_eq!(
997+
gossip_interpolate_weight(1, 1, ALPHA_MIN + (lpf::SCALE.get() / 2)),
998+
1
999+
);
9941000

9951001
// Test with base = 0
996-
assert_eq!(linearly_interpolate(0, 0), 0);
997-
assert_eq!(linearly_interpolate(0, lpf::SCALE.get()), 0);
998-
assert_eq!(linearly_interpolate(0, lpf::SCALE.get() / 2), 0);
1002+
assert_eq!(gossip_interpolate_weight(0, 0, ALPHA_MIN), 0);
1003+
assert_eq!(gossip_interpolate_weight(0, 0, ALPHA_MAX), 0);
1004+
assert_eq!(
1005+
gossip_interpolate_weight(0, 0, ALPHA_MIN + (lpf::SCALE.get() / 2)),
1006+
0
1007+
);
9991008
}
10001009

10011010
#[test]
10021011
fn test_interpolate_rounding() {
10031012
let base = 3;
10041013
let t = lpf::SCALE.get() / 3;
1005-
let result = linearly_interpolate(base, t);
1014+
let result = gossip_interpolate_weight(base, base * base, ALPHA_MIN + t);
10061015

10071016
assert!(result >= 3);
10081017
assert!(result <= 9);
@@ -1024,9 +1033,8 @@ mod tests {
10241033
let target_alpha = alpha_min + lpf::SCALE.get() / 2; // 1.5 * SCALE
10251034
let filtered_alpha = lpf::filter_alpha(prev_alpha, target_alpha, config);
10261035

1027-
let t = filtered_alpha.saturating_sub(alpha_min);
10281036
let base = 2;
1029-
let result = linearly_interpolate(base, t);
1037+
let result = gossip_interpolate_weight(base, base * base, filtered_alpha);
10301038

10311039
assert!(result >= base);
10321040
assert!(result <= base * base);

low-pass-filter/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub mod api {
1717
// Fixed point scale for K and `alpha` calculation
1818
pub const SCALE: NonZeroU64 = NonZeroU64::new(1_000_000).unwrap();
1919
// 2 * pi * SCALE
20-
const TWO_PI_SCALED: u64 = 6_283_185;
20+
const TWO_PI_SCALED: u64 = (2.0 * std::f64::consts::PI * SCALE.get() as f64) as u64;
2121

2222
#[derive(Clone)]
2323
pub struct FilterConfig {

0 commit comments

Comments
 (0)