gas_limit for blocks, mined by Parity will be divisible by 37 (#4154)
* gas_limit for new blocks will divide evenly by 13 * increased PARITY_GAS_LIMIT_DETERMINANT to 37 * separate method for marking mined block * debug_asserts(gas_limit within protocol range) * round_block_gas_limit method is now static * made round_block_gas_limit free-function * multiplier->multiple [ci skip]
This commit is contained in:
parent
76daf50876
commit
bac6293309
@ -31,6 +31,9 @@ use ethjson;
|
|||||||
use rlp::{self, UntrustedRlp, View};
|
use rlp::{self, UntrustedRlp, View};
|
||||||
use blockchain::extras::BlockDetails;
|
use blockchain::extras::BlockDetails;
|
||||||
|
|
||||||
|
/// Parity tries to round block.gas_limit to multiple of this constant
|
||||||
|
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
|
||||||
|
|
||||||
/// Ethash params.
|
/// Ethash params.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct EthashParams {
|
pub struct EthashParams {
|
||||||
@ -180,14 +183,23 @@ impl Engine for Ethash {
|
|||||||
let bound_divisor = self.ethash_params.gas_limit_bound_divisor;
|
let bound_divisor = self.ethash_params.gas_limit_bound_divisor;
|
||||||
let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into();
|
let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into();
|
||||||
let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into();
|
let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into();
|
||||||
if gas_limit < gas_floor_target {
|
let gas_limit = if gas_limit < gas_floor_target {
|
||||||
min(gas_floor_target, upper_limit)
|
let gas_limit = min(gas_floor_target, upper_limit);
|
||||||
|
round_block_gas_limit(gas_limit, lower_limit, upper_limit)
|
||||||
} else if gas_limit > gas_ceil_target {
|
} else if gas_limit > gas_ceil_target {
|
||||||
max(gas_ceil_target, lower_limit)
|
let gas_limit = max(gas_ceil_target, lower_limit);
|
||||||
|
round_block_gas_limit(gas_limit, lower_limit, upper_limit)
|
||||||
} else {
|
} else {
|
||||||
max(gas_floor_target, min(min(gas_ceil_target, upper_limit),
|
let total_lower_limit = max(lower_limit, gas_floor_target);
|
||||||
lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor))
|
let total_upper_limit = min(upper_limit, gas_ceil_target);
|
||||||
}
|
let gas_limit = max(gas_floor_target, min(total_upper_limit,
|
||||||
|
lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor));
|
||||||
|
round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit)
|
||||||
|
};
|
||||||
|
// ensure that we are not violating protocol limits
|
||||||
|
debug_assert!(gas_limit >= lower_limit);
|
||||||
|
debug_assert!(gas_limit <= upper_limit);
|
||||||
|
gas_limit
|
||||||
};
|
};
|
||||||
header.set_difficulty(difficulty);
|
header.set_difficulty(difficulty);
|
||||||
header.set_gas_limit(gas_limit);
|
header.set_gas_limit(gas_limit);
|
||||||
@ -334,6 +346,23 @@ pub fn is_new_best_block(best_total_difficulty: U256, parent_details: &BlockDeta
|
|||||||
parent_details.total_difficulty + new_header.difficulty() > best_total_difficulty
|
parent_details.total_difficulty + new_header.difficulty() > best_total_difficulty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to round gas_limit a bit so that:
|
||||||
|
// 1) it will still be in desired range
|
||||||
|
// 2) it will be a nearest (with tendency to increase) multiple of PARITY_GAS_LIMIT_DETERMINANT
|
||||||
|
fn round_block_gas_limit(gas_limit: U256, lower_limit: U256, upper_limit: U256) -> U256 {
|
||||||
|
let increased_gas_limit = gas_limit + (PARITY_GAS_LIMIT_DETERMINANT - gas_limit % PARITY_GAS_LIMIT_DETERMINANT);
|
||||||
|
if increased_gas_limit > upper_limit {
|
||||||
|
let decreased_gas_limit = increased_gas_limit - PARITY_GAS_LIMIT_DETERMINANT;
|
||||||
|
if decreased_gas_limit < lower_limit {
|
||||||
|
gas_limit
|
||||||
|
} else {
|
||||||
|
decreased_gas_limit
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
increased_gas_limit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
||||||
impl Ethash {
|
impl Ethash {
|
||||||
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
|
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
|
||||||
@ -431,11 +460,12 @@ mod tests {
|
|||||||
use util::*;
|
use util::*;
|
||||||
use block::*;
|
use block::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
|
use engines::Engine;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use error::{BlockError, Error};
|
use error::{BlockError, Error};
|
||||||
use header::Header;
|
use header::Header;
|
||||||
use super::super::{new_morden, new_homestead_test};
|
use super::super::{new_morden, new_homestead_test};
|
||||||
use super::{Ethash, EthashParams};
|
use super::{Ethash, EthashParams, PARITY_GAS_LIMIT_DETERMINANT};
|
||||||
use rlp;
|
use rlp;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -773,4 +803,47 @@ mod tests {
|
|||||||
ethash.calculate_difficulty(&header, &parent_header)
|
ethash.calculate_difficulty(&header, &parent_header)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn gas_limit_is_multiple_of_determinant() {
|
||||||
|
let spec = new_homestead_test();
|
||||||
|
let ethash = Ethash::new(spec.params, get_default_ethash_params(), BTreeMap::new());
|
||||||
|
let mut parent = Header::new();
|
||||||
|
let mut header = Header::new();
|
||||||
|
header.set_number(1);
|
||||||
|
|
||||||
|
// this test will work for this constant only
|
||||||
|
assert_eq!(PARITY_GAS_LIMIT_DETERMINANT, U256::from(37));
|
||||||
|
|
||||||
|
// when parent.gas_limit < gas_floor_target:
|
||||||
|
parent.set_gas_limit(U256::from(50_000));
|
||||||
|
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000));
|
||||||
|
assert_eq!(*header.gas_limit(), U256::from(50_024));
|
||||||
|
|
||||||
|
// when parent.gas_limit > gas_ceil_target:
|
||||||
|
parent.set_gas_limit(U256::from(250_000));
|
||||||
|
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000));
|
||||||
|
assert_eq!(*header.gas_limit(), U256::from(249_787));
|
||||||
|
|
||||||
|
// when parent.gas_limit is in miner's range
|
||||||
|
header.set_gas_used(U256::from(150_000));
|
||||||
|
parent.set_gas_limit(U256::from(150_000));
|
||||||
|
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000));
|
||||||
|
assert_eq!(*header.gas_limit(), U256::from(150_035));
|
||||||
|
|
||||||
|
// when parent.gas_limit is in miner's range
|
||||||
|
// && we can NOT increase it to be multiple of constant
|
||||||
|
header.set_gas_used(U256::from(150_000));
|
||||||
|
parent.set_gas_limit(U256::from(150_000));
|
||||||
|
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(150_002));
|
||||||
|
assert_eq!(*header.gas_limit(), U256::from(149_998));
|
||||||
|
|
||||||
|
// when parent.gas_limit is in miner's range
|
||||||
|
// && we can NOT increase it to be multiple of constant
|
||||||
|
// && we can NOT decrease it to be multiple of constant
|
||||||
|
header.set_gas_used(U256::from(150_000));
|
||||||
|
parent.set_gas_limit(U256::from(150_000));
|
||||||
|
ethash.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002));
|
||||||
|
assert_eq!(*header.gas_limit(), U256::from(150_002));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user