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 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.
 | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub struct EthashParams { | ||||
| @ -180,14 +183,23 @@ impl Engine for Ethash { | ||||
| 			let bound_divisor = self.ethash_params.gas_limit_bound_divisor; | ||||
| 			let lower_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 { | ||||
| 				min(gas_floor_target, upper_limit) | ||||
| 			let gas_limit = if gas_limit < gas_floor_target { | ||||
| 				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 { | ||||
| 				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 { | ||||
| 				max(gas_floor_target, min(min(gas_ceil_target, upper_limit), | ||||
| 					lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor)) | ||||
| 			} | ||||
| 				let total_lower_limit = max(lower_limit, gas_floor_target); | ||||
| 				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_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 | ||||
| } | ||||
| 
 | ||||
| // 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))] | ||||
| impl Ethash { | ||||
| 	fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 { | ||||
| @ -431,11 +460,12 @@ mod tests { | ||||
| 	use util::*; | ||||
| 	use block::*; | ||||
| 	use tests::helpers::*; | ||||
| 	use engines::Engine; | ||||
| 	use env_info::EnvInfo; | ||||
| 	use error::{BlockError, Error}; | ||||
| 	use header::Header; | ||||
| 	use super::super::{new_morden, new_homestead_test}; | ||||
| 	use super::{Ethash, EthashParams}; | ||||
| 	use super::{Ethash, EthashParams, PARITY_GAS_LIMIT_DETERMINANT}; | ||||
| 	use rlp; | ||||
| 
 | ||||
| 	#[test] | ||||
| @ -773,4 +803,47 @@ mod tests { | ||||
| 			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