mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
Secondary PoW factor adjustment adjustments
This commit is contained in:
parent
45a5655cec
commit
eeb7680981
2 changed files with 88 additions and 12 deletions
|
@ -18,7 +18,7 @@
|
||||||
//! enough, consensus-relevant constants and short functions should be kept
|
//! enough, consensus-relevant constants and short functions should be kept
|
||||||
//! here.
|
//! here.
|
||||||
|
|
||||||
use std::cmp::max;
|
use std::cmp::{max, min};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use global;
|
use global;
|
||||||
|
@ -293,8 +293,10 @@ where
|
||||||
HeaderInfo::from_diff_scaling(Difficulty::from_num(difficulty), sec_pow_scaling)
|
HeaderInfo::from_diff_scaling(Difficulty::from_num(difficulty), sec_pow_scaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const MAX_SECONDARY_SCALING: u64 = (::std::u32::MAX / 70) as u64;
|
||||||
|
|
||||||
/// Factor by which the secondary proof of work difficulty will be adjusted
|
/// Factor by which the secondary proof of work difficulty will be adjusted
|
||||||
fn secondary_pow_scaling(height: u64, diff_data: &Vec<HeaderInfo>) -> u32 {
|
pub fn secondary_pow_scaling(height: u64, diff_data: &Vec<HeaderInfo>) -> u32 {
|
||||||
// median of past scaling factors, scaling is 1 if none found
|
// median of past scaling factors, scaling is 1 if none found
|
||||||
let mut scalings = diff_data
|
let mut scalings = diff_data
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -305,18 +307,30 @@ fn secondary_pow_scaling(height: u64, diff_data: &Vec<HeaderInfo>) -> u32 {
|
||||||
}
|
}
|
||||||
scalings.sort();
|
scalings.sort();
|
||||||
let scaling_median = scalings[scalings.len() / 2] as u64;
|
let scaling_median = scalings[scalings.len() / 2] as u64;
|
||||||
let secondary_count = diff_data.iter().filter(|n| n.is_secondary).count() as u64;
|
let secondary_count = max(diff_data.iter().filter(|n| n.is_secondary).count(), 1) as u64;
|
||||||
|
|
||||||
// what's the ideal ratio at the current height
|
// what's the ideal ratio at the current height
|
||||||
let ratio = secondary_pow_ratio(height);
|
let ratio = secondary_pow_ratio(height);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"-- {} {} {} {}",
|
||||||
|
scaling_median,
|
||||||
|
secondary_count,
|
||||||
|
diff_data.len(),
|
||||||
|
ratio
|
||||||
|
);
|
||||||
// adjust the past median based on ideal ratio vs actual ratio
|
// adjust the past median based on ideal ratio vs actual ratio
|
||||||
let scaling = scaling_median * secondary_count * 100 / ratio / diff_data.len() as u64;
|
let scaling = scaling_median * diff_data.len() as u64 * ratio / 100 / secondary_count as u64;
|
||||||
if scaling == 0 {
|
|
||||||
1
|
// various bounds
|
||||||
|
let bounded_scaling = if scaling < scaling_median / 4 || scaling == 0 {
|
||||||
|
max(scaling_median / 4, 1)
|
||||||
|
} else if scaling > MAX_SECONDARY_SCALING || scaling > scaling_median * 4 {
|
||||||
|
min(MAX_SECONDARY_SCALING, scaling_median * 4)
|
||||||
} else {
|
} else {
|
||||||
scaling as u32
|
scaling
|
||||||
}
|
};
|
||||||
|
bounded_scaling as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Median timestamp within the time window starting at `from` with the
|
/// Median timestamp within the time window starting at `from` with the
|
||||||
|
|
|
@ -17,10 +17,7 @@ extern crate grin_core as core;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
|
|
||||||
use chrono::prelude::Utc;
|
use chrono::prelude::Utc;
|
||||||
use core::consensus::{
|
use core::consensus::*;
|
||||||
next_difficulty, valid_header_version, HeaderInfo, BLOCK_TIME_WINDOW, DAMP_FACTOR,
|
|
||||||
DIFFICULTY_ADJUST_WINDOW, MEDIAN_TIME_INDEX, MEDIAN_TIME_WINDOW, UPPER_TIME_BOUND,
|
|
||||||
};
|
|
||||||
use core::global;
|
use core::global;
|
||||||
use core::pow::Difficulty;
|
use core::pow::Difficulty;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
@ -514,6 +511,71 @@ fn next_target_adjustment() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secondary_pow_scale() {
|
||||||
|
let window = DIFFICULTY_ADJUST_WINDOW + MEDIAN_TIME_WINDOW;
|
||||||
|
let mut hi = HeaderInfo::from_diff_scaling(Difficulty::from_num(10), 100);
|
||||||
|
|
||||||
|
// all primary, factor should be multiplied by 4 (max adjustment) so it
|
||||||
|
// becomes easier to find a high difficulty block
|
||||||
|
assert_eq!(
|
||||||
|
secondary_pow_scaling(1, &(0..window).map(|_| hi.clone()).collect()),
|
||||||
|
400
|
||||||
|
);
|
||||||
|
// all secondary on 90%, factor should lose 10%
|
||||||
|
hi.is_secondary = true;
|
||||||
|
assert_eq!(
|
||||||
|
secondary_pow_scaling(1, &(0..window).map(|_| hi.clone()).collect()),
|
||||||
|
90
|
||||||
|
);
|
||||||
|
// all secondary on 1%, should be divided by 4 (max adjustment)
|
||||||
|
assert_eq!(
|
||||||
|
secondary_pow_scaling(890_000, &(0..window).map(|_| hi.clone()).collect()),
|
||||||
|
25
|
||||||
|
);
|
||||||
|
// same as above, testing lowest bound
|
||||||
|
let mut low_hi = HeaderInfo::from_diff_scaling(Difficulty::from_num(10), 3);
|
||||||
|
low_hi.is_secondary = true;
|
||||||
|
assert_eq!(
|
||||||
|
secondary_pow_scaling(890_000, &(0..window).map(|_| low_hi.clone()).collect()),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
// just about the right ratio, also playing with median
|
||||||
|
let primary_hi = HeaderInfo::from_diff_scaling(Difficulty::from_num(10), 50);
|
||||||
|
assert_eq!(
|
||||||
|
secondary_pow_scaling(
|
||||||
|
1,
|
||||||
|
&(0..(window / 10))
|
||||||
|
.map(|_| primary_hi.clone())
|
||||||
|
.chain((0..(window * 9 / 10)).map(|_| hi.clone()))
|
||||||
|
.collect()
|
||||||
|
),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
// 95% secondary, should come down
|
||||||
|
assert_eq!(
|
||||||
|
secondary_pow_scaling(
|
||||||
|
1,
|
||||||
|
&(0..(window / 20))
|
||||||
|
.map(|_| primary_hi.clone())
|
||||||
|
.chain((0..(window * 95 / 100)).map(|_| hi.clone()))
|
||||||
|
.collect()
|
||||||
|
),
|
||||||
|
94
|
||||||
|
);
|
||||||
|
// 40% secondary, should come up
|
||||||
|
assert_eq!(
|
||||||
|
secondary_pow_scaling(
|
||||||
|
1,
|
||||||
|
&(0..(window * 6 / 10))
|
||||||
|
.map(|_| primary_hi.clone())
|
||||||
|
.chain((0..(window * 4 / 10)).map(|_| hi.clone()))
|
||||||
|
.collect()
|
||||||
|
),
|
||||||
|
112
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hard_forks() {
|
fn hard_forks() {
|
||||||
assert!(valid_header_version(0, 1));
|
assert!(valid_header_version(0, 1));
|
||||||
|
|
Loading…
Reference in a new issue