Fix secondary scaling bugs; add global::is_mainnet(); use it to change pre-genesis pow type (#2205)
This commit is contained in:
committed by
Ignotus Peverell
parent
84d2966663
commit
976bf1dbae
+14
-18
@@ -84,11 +84,6 @@ pub const SECOND_POW_EDGE_BITS: u8 = 29;
|
||||
/// Cuckoo graph sizes, changing this would hard fork
|
||||
pub const BASE_EDGE_BITS: u8 = 24;
|
||||
|
||||
/// Maximum scaling factor for secondary pow, enforced in diff retargetting
|
||||
/// increasing scaling factor increases frequency of secondary blocks
|
||||
/// ONLY IN TESTNET4 LIMITED TO ABOUT 8 TIMES THE NATURAL SCALE
|
||||
pub const MAX_SECONDARY_SCALING: u64 = 8 << 11;
|
||||
|
||||
/// Default number of blocks in the past when cross-block cut-through will start
|
||||
/// happening. Needs to be long enough to not overlap with a long reorg.
|
||||
/// Rational
|
||||
@@ -181,9 +176,14 @@ pub fn graph_weight(height: u64, edge_bits: u8) -> u64 {
|
||||
(2 << (edge_bits - global::base_edge_bits()) as u64) * xpr_edge_bits
|
||||
}
|
||||
|
||||
/// minimum difficulty to avoid getting stuck when trying to increase subject to dampening
|
||||
/// Minimum difficulty, enforced in diff retargetting
|
||||
/// avoids getting stuck when trying to increase difficulty subject to dampening
|
||||
pub const MIN_DIFFICULTY: u64 = DIFFICULTY_DAMP_FACTOR;
|
||||
|
||||
/// Minimum scaling factor for AR pow, enforced in diff retargetting
|
||||
/// avoids getting stuck when trying to increase ar_scale subject to dampening
|
||||
pub const MIN_AR_SCALE: u64 = AR_SCALE_DAMP_FACTOR;
|
||||
|
||||
/// unit difficulty, equal to graph_weight(SECOND_POW_EDGE_BITS)
|
||||
pub const UNIT_DIFFICULTY: u64 =
|
||||
((2 as u64) << (SECOND_POW_EDGE_BITS - BASE_EDGE_BITS)) * (SECOND_POW_EDGE_BITS as u64);
|
||||
@@ -231,7 +231,7 @@ impl HeaderInfo {
|
||||
timestamp,
|
||||
difficulty,
|
||||
secondary_scaling: global::initial_graph_weight(),
|
||||
is_secondary: false,
|
||||
is_secondary: global::is_mainnet(), // floonet launched with false:-(
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,8 +280,8 @@ where
|
||||
// DIFFICULTY_ADJUST_WINDOW + 1 (for initial block time bound)
|
||||
let diff_data = global::difficulty_data_to_vector(cursor);
|
||||
|
||||
// First, get the ratio of secondary PoW vs primary
|
||||
let sec_pow_scaling = secondary_pow_scaling(height, &diff_data);
|
||||
// First, get the ratio of secondary PoW vs primary, skipping initial header
|
||||
let sec_pow_scaling = secondary_pow_scaling(height, &diff_data[1..]);
|
||||
|
||||
// Get the timestamp delta across the window
|
||||
let ts_delta: u64 =
|
||||
@@ -306,13 +306,10 @@ where
|
||||
HeaderInfo::from_diff_scaling(Difficulty::from_num(difficulty), sec_pow_scaling)
|
||||
}
|
||||
|
||||
/// Count the number of "secondary" (AR) blocks in the provided window of blocks.
|
||||
/// Note: we skip the first one, but testnet4 was incorrectly including it before
|
||||
/// the hardfork.
|
||||
fn ar_count(_height: u64, diff_data: &[HeaderInfo]) -> u64 {
|
||||
/// Count, in units of 1/100 (a percent), the number of "secondary" (AR) blocks in the provided window of blocks.
|
||||
pub fn ar_count(_height: u64, diff_data: &[HeaderInfo]) -> u64 {
|
||||
100 * diff_data
|
||||
.iter()
|
||||
.skip(1)
|
||||
.filter(|n| n.is_secondary)
|
||||
.count() as u64
|
||||
}
|
||||
@@ -322,7 +319,6 @@ pub fn secondary_pow_scaling(height: u64, diff_data: &[HeaderInfo]) -> u32 {
|
||||
// Get the scaling factor sum of the last DIFFICULTY_ADJUST_WINDOW elements
|
||||
let scale_sum: u64 = diff_data
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|dd| dd.secondary_scaling as u64)
|
||||
.sum();
|
||||
|
||||
@@ -341,10 +337,10 @@ pub fn secondary_pow_scaling(height: u64, diff_data: &[HeaderInfo]) -> u32 {
|
||||
target_count,
|
||||
CLAMP_FACTOR,
|
||||
);
|
||||
let scale = scale_sum * target_pct / adj_count;
|
||||
let scale = scale_sum * target_pct / max(1, adj_count);
|
||||
|
||||
// minimum difficulty avoids getting stuck due to dampening
|
||||
max(MIN_DIFFICULTY, min(scale, MAX_SECONDARY_SCALING)) as u32
|
||||
// minimum AR scale avoids getting stuck due to dampening
|
||||
max(MIN_AR_SCALE, scale) as u32
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -266,6 +266,12 @@ pub fn is_testnet() -> bool {
|
||||
ChainTypes::Floonet == *param_ref
|
||||
}
|
||||
|
||||
/// Are we for real?
|
||||
pub fn is_mainnet() -> bool {
|
||||
let param_ref = CHAIN_TYPE.read();
|
||||
ChainTypes::Mainnet == *param_ref
|
||||
}
|
||||
|
||||
/// Helper function to get a nonce known to create a valid POW on
|
||||
/// the genesis block, to prevent it taking ages. Should be fine for now
|
||||
/// as the genesis block POW solution turns out to be the same for every new
|
||||
|
||||
+12
-86
@@ -541,118 +541,44 @@ fn test_secondary_pow_scale() {
|
||||
let window = DIFFICULTY_ADJUST_WINDOW;
|
||||
let mut hi = HeaderInfo::from_diff_scaling(Difficulty::from_num(10), 100);
|
||||
|
||||
// floonet testing
|
||||
{
|
||||
global::set_mining_mode(global::ChainTypes::Floonet);
|
||||
assert_eq!(global::is_testnet(), true);
|
||||
|
||||
// all primary, factor should increase so it becomes easier to find a high
|
||||
// difficulty block
|
||||
hi.is_secondary = false;
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(1, &(0..window).map(|_| hi.clone()).collect::<Vec<_>>()),
|
||||
106
|
||||
);
|
||||
// all secondary on 90%, factor should go down a bit
|
||||
hi.is_secondary = true;
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(1, &(0..window).map(|_| hi.clone()).collect::<Vec<_>>()),
|
||||
97
|
||||
);
|
||||
// all secondary on 1%, factor should go down to bound (divide by 2)
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(
|
||||
890_000,
|
||||
&(0..window).map(|_| hi.clone()).collect::<Vec<_>>()
|
||||
),
|
||||
67
|
||||
);
|
||||
// same as above, testing lowest bound
|
||||
let mut low_hi =
|
||||
HeaderInfo::from_diff_scaling(Difficulty::from_num(10), MIN_DIFFICULTY as u32);
|
||||
low_hi.is_secondary = true;
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(
|
||||
890_000,
|
||||
&(0..window).map(|_| low_hi.clone()).collect::<Vec<_>>()
|
||||
),
|
||||
MIN_DIFFICULTY as u32
|
||||
);
|
||||
// just about the right ratio, also no longer playing with median
|
||||
let mut primary_hi = HeaderInfo::from_diff_scaling(Difficulty::from_num(10), 50);
|
||||
primary_hi.is_secondary = false;
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(
|
||||
1,
|
||||
&(0..(window / 10))
|
||||
.map(|_| primary_hi.clone())
|
||||
.chain((0..(window * 9 / 10)).map(|_| hi.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
),
|
||||
94
|
||||
);
|
||||
// 95% secondary, should come down based on 97.5 average
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(
|
||||
1,
|
||||
&(0..(window / 20))
|
||||
.map(|_| primary_hi.clone())
|
||||
.chain((0..(window * 95 / 100)).map(|_| hi.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
),
|
||||
96
|
||||
);
|
||||
// 40% secondary, should come up based on 70 average
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(
|
||||
1,
|
||||
&(0..(window * 6 / 10))
|
||||
.map(|_| primary_hi.clone())
|
||||
.chain((0..(window * 4 / 10)).map(|_| hi.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
),
|
||||
72
|
||||
);
|
||||
}
|
||||
|
||||
// mainnet testing
|
||||
{
|
||||
global::set_mining_mode(global::ChainTypes::Mainnet);
|
||||
assert_eq!(global::is_testnet(), false);
|
||||
assert_eq!(global::is_mainnet(), true);
|
||||
|
||||
// all primary, factor should increase so it becomes easier to find a high
|
||||
// difficulty block
|
||||
hi.is_secondary = false;
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(1, &(0..window).map(|_| hi.clone()).collect::<Vec<_>>()),
|
||||
106
|
||||
108
|
||||
);
|
||||
// all secondary on 90%, factor should go down a bit
|
||||
hi.is_secondary = true;
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(1, &(0..window).map(|_| hi.clone()).collect::<Vec<_>>()),
|
||||
97
|
||||
99
|
||||
);
|
||||
// all secondary on 1%, factor should go down to bound (divide by 2)
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(
|
||||
890_000,
|
||||
2 * YEAR_HEIGHT * 83 / 90,
|
||||
&(0..window).map(|_| hi.clone()).collect::<Vec<_>>()
|
||||
),
|
||||
67
|
||||
50
|
||||
);
|
||||
// same as above, testing lowest bound
|
||||
let mut low_hi =
|
||||
HeaderInfo::from_diff_scaling(Difficulty::from_num(10), MIN_DIFFICULTY as u32);
|
||||
HeaderInfo::from_diff_scaling(Difficulty::from_num(10), MIN_AR_SCALE as u32);
|
||||
low_hi.is_secondary = true;
|
||||
assert_eq!(
|
||||
secondary_pow_scaling(
|
||||
890_000,
|
||||
2 * YEAR_HEIGHT,
|
||||
&(0..window).map(|_| low_hi.clone()).collect::<Vec<_>>()
|
||||
),
|
||||
MIN_DIFFICULTY as u32
|
||||
MIN_AR_SCALE as u32
|
||||
);
|
||||
// just about the right ratio, also no longer playing with median
|
||||
// the right ratio of 95% secondary
|
||||
let mut primary_hi = HeaderInfo::from_diff_scaling(Difficulty::from_num(10), 50);
|
||||
primary_hi.is_secondary = false;
|
||||
assert_eq!(
|
||||
@@ -663,7 +589,7 @@ fn test_secondary_pow_scale() {
|
||||
.chain((0..(window * 9 / 10)).map(|_| hi.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
),
|
||||
94
|
||||
95, // avg ar_scale of 10% * 50 + 90% * 100
|
||||
);
|
||||
// 95% secondary, should come down based on 97.5 average
|
||||
assert_eq!(
|
||||
@@ -674,7 +600,7 @@ fn test_secondary_pow_scale() {
|
||||
.chain((0..(window * 95 / 100)).map(|_| hi.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
),
|
||||
96
|
||||
97
|
||||
);
|
||||
// 40% secondary, should come up based on 70 average
|
||||
assert_eq!(
|
||||
@@ -685,7 +611,7 @@ fn test_secondary_pow_scale() {
|
||||
.chain((0..(window * 4 / 10)).map(|_| hi.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
),
|
||||
72
|
||||
73
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user