Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Configurable gas limit cap. #1405

Merged
merged 4 commits into from
Jun 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ethcore/src/basic_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl Engine for BasicAuthority {
Schedule::new_homestead()
}

fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256) {
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) {
header.difficulty = parent.difficulty;
header.gas_limit = {
let gas_limit = parent.gas_limit;
Expand Down Expand Up @@ -254,7 +254,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, addr, 3141562.into(), vec![]).unwrap();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
let b = b.close_and_lock();
let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();
assert!(b.try_seal(engine.deref(), seal).is_ok());
Expand Down
12 changes: 6 additions & 6 deletions ethcore/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ impl<'x> OpenBlock<'x> {
last_hashes: LastHashes,
dao_rescue_block_gas_limit: Option<U256>,
author: Address,
gas_floor_target: U256,
gas_range_target: (U256, U256),
extra_data: Bytes,
) -> Result<Self, Error> {
let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()));
Expand All @@ -241,7 +241,7 @@ impl<'x> OpenBlock<'x> {
r.block.base.header.extra_data = extra_data;
r.block.base.header.note_dirty();

engine.populate_from_parent(&mut r.block.base.header, parent, gas_floor_target);
engine.populate_from_parent(&mut r.block.base.header, parent, gas_range_target.0, gas_range_target.1);
engine.on_new_block(&mut r.block);
Ok(r)
}
Expand Down Expand Up @@ -480,7 +480,7 @@ pub fn enact(
}
}

let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), 3141562.into(), header.extra_data().clone()));
let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), (3141562.into(), 31415620.into()), header.extra_data().clone()));
b.set_difficulty(*header.difficulty());
b.set_gas_limit(*header.gas_limit());
b.set_timestamp(header.timestamp());
Expand Down Expand Up @@ -555,7 +555,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), 3141562.into(), vec![]).unwrap();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let b = b.close_and_lock();
let _ = b.seal(engine.deref(), vec![]);
}
Expand All @@ -571,7 +571,7 @@ mod tests {
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), 3141562.into(), vec![]).unwrap()
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
.close_and_lock().seal(engine.deref(), vec![]).unwrap();
let orig_bytes = b.rlp_bytes();
let orig_db = b.drain();
Expand Down Expand Up @@ -599,7 +599,7 @@ mod tests {
let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut());
let vm_factory = Default::default();
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), 3141562.into(), vec![]).unwrap();
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let mut uncle1_header = Header::new();
uncle1_header.extra_data = b"uncle1".to_vec();
let mut uncle2_header = Header::new();
Expand Down
4 changes: 2 additions & 2 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
}

impl<V> MiningBlockChainClient for Client<V> where V: Verifier {
fn prepare_open_block(&self, author: Address, gas_floor_target: U256, extra_data: Bytes) -> OpenBlock {
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
let engine = self.engine.deref().deref();
let h = self.chain.best_block_hash();

Expand All @@ -810,7 +810,7 @@ impl<V> MiningBlockChainClient for Client<V> where V: Verifier {
self.build_last_hashes(h.clone()),
self.dao_rescue_block_gas_limit(h.clone()),
author,
gas_floor_target,
gas_range_target,
extra_data,
).expect("OpenBlock::new only fails if parent state root invalid; state root of best block's header is never invalid; qed");

Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,6 @@ pub trait BlockChainClient : Sync + Send {
/// Extended client interface used for mining
pub trait MiningBlockChainClient : BlockChainClient {
/// Returns OpenBlock prepared for closing.
fn prepare_open_block(&self, author: Address, gas_floor_target: U256, extra_data: Bytes)
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes)
-> OpenBlock;
}
2 changes: 1 addition & 1 deletion ethcore/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ impl TestBlockChainClient {
}

impl MiningBlockChainClient for TestBlockChainClient {
fn prepare_open_block(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes) -> OpenBlock {
fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock {
unimplemented!();
}
}
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub trait Engine : Sync + Send {

/// Don't forget to call Super::populate_from_parent when subclassing & overriding.
// TODO: consider including State in the params.
fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256) {
fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256, _gas_ceil_target: U256) {
header.difficulty = parent.difficulty;
header.gas_limit = parent.gas_limit;
header.note_dirty();
Expand Down
16 changes: 10 additions & 6 deletions ethcore/src/ethereum/ethash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,20 @@ impl Engine for Ethash {
}
}

fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256) {
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, gas_ceil_target: U256) {
header.difficulty = self.calculate_difficuty(header, parent);
header.gas_limit = {
let gas_limit = parent.gas_limit;
let bound_divisor = self.ethash_params.gas_limit_bound_divisor;
if gas_limit < gas_floor_target {
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
} else if gas_limit > gas_ceil_target {
max(gas_ceil_target, gas_limit - gas_limit / bound_divisor + 1.into())
} else {
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into() + (header.gas_used * 6.into() / 5.into()) / bound_divisor)
min(gas_ceil_target,
max(gas_floor_target,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

min here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

gas_limit - gas_limit / bound_divisor + 1.into() +
(header.gas_used * 6.into() / 5.into()) / bound_divisor))
}
};
header.note_dirty();
Expand Down Expand Up @@ -237,8 +242,7 @@ impl Ethash {
let mut target = if header.number < frontier_limit {
if header.timestamp >= parent.timestamp + duration_limit {
parent.difficulty - (parent.difficulty / difficulty_bound_divisor)
}
else {
} else {
parent.difficulty + (parent.difficulty / difficulty_bound_divisor)
}
}
Expand Down Expand Up @@ -323,7 +327,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), 3141562.into(), vec![]).unwrap();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
}
Expand All @@ -338,7 +342,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default();
let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), 3141562.into(), vec![]).unwrap();
let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
let mut uncle = Header::new();
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
uncle.author = uncle_author.clone();
Expand Down
25 changes: 17 additions & 8 deletions ethcore/src/miner/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub struct Miner {
force_sealing: bool,
sealing_enabled: AtomicBool,
sealing_block_last_request: Mutex<u64>,
gas_floor_target: RwLock<U256>,
gas_range_target: RwLock<(U256, U256)>,
author: RwLock<Address>,
extra_data: RwLock<Bytes>,
spec: Spec,
Expand All @@ -55,7 +55,7 @@ impl Default for Miner {
sealing_enabled: AtomicBool::new(false),
sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(UsingQueue::new(5)),
gas_floor_target: RwLock::new(U256::zero()),
gas_range_target: RwLock::new((U256::zero(), U256::zero())),
author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()),
accounts: None,
Expand All @@ -73,7 +73,7 @@ impl Miner {
sealing_enabled: AtomicBool::new(force_sealing),
sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(UsingQueue::new(5)),
gas_floor_target: RwLock::new(U256::zero()),
gas_range_target: RwLock::new((U256::zero(), U256::zero())),
author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()),
accounts: None,
Expand All @@ -89,7 +89,7 @@ impl Miner {
sealing_enabled: AtomicBool::new(force_sealing),
sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(UsingQueue::new(5)),
gas_floor_target: RwLock::new(U256::zero()),
gas_range_target: RwLock::new((U256::zero(), U256::zero())),
author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()),
accounts: Some(accounts),
Expand Down Expand Up @@ -131,7 +131,7 @@ impl Miner {
trace!(target: "miner", "No existing work - making new block");
chain.prepare_open_block(
self.author(),
self.gas_floor_target(),
(self.gas_floor_target(), self.gas_ceil_target()),
self.extra_data()
)
}
Expand Down Expand Up @@ -341,7 +341,11 @@ impl MinerService for Miner {

/// Set the gas limit we wish to target when sealing a new block.
fn set_gas_floor_target(&self, target: U256) {
*self.gas_floor_target.write().unwrap() = target;
self.gas_range_target.write().unwrap().0 = target;
}

fn set_gas_ceil_target(&self, target: U256) {
self.gas_range_target.write().unwrap().1 = target;
}

fn set_minimal_gas_price(&self, min_gas_price: U256) {
Expand All @@ -358,7 +362,7 @@ impl MinerService for Miner {
}

fn sensible_gas_limit(&self) -> U256 {
*self.gas_floor_target.read().unwrap() / 5.into()
self.gas_range_target.read().unwrap().0 / 5.into()
}

fn transactions_limit(&self) -> usize {
Expand All @@ -381,7 +385,12 @@ impl MinerService for Miner {

/// Get the gas limit we wish to target when sealing a new block.
fn gas_floor_target(&self) -> U256 {
*self.gas_floor_target.read().unwrap()
self.gas_range_target.read().unwrap().0
}

/// Get the gas limit we wish to target when sealing a new block.
fn gas_ceil_target(&self) -> U256 {
self.gas_range_target.read().unwrap().1
}

fn import_transactions<T>(&self, chain: &MiningBlockChainClient, transactions: Vec<SignedTransaction>, fetch_account: T) ->
Expand Down
11 changes: 9 additions & 2 deletions ethcore/src/miner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,19 @@ pub trait MinerService : Send + Sync {
/// Set minimal gas price of transaction to be accepted for mining.
fn set_minimal_gas_price(&self, min_gas_price: U256);

/// Get the gas limit we wish to target when sealing a new block.
/// Get the lower bound of the gas limit we wish to target when sealing a new block.
fn gas_floor_target(&self) -> U256;

/// Set the gas limit we wish to target when sealing a new block.
/// Get the upper bound of the gas limit we wish to target when sealing a new block.
fn gas_ceil_target(&self) -> U256;

// TODO: coalesce into single set_range function.
/// Set the lower bound of gas limit we wish to target when sealing a new block.
fn set_gas_floor_target(&self, target: U256);

/// Set the upper bound of gas limit we wish to target when sealing a new block.
fn set_gas_ceil_target(&self, target: U256);

/// Get current transactions limit in queue.
fn transactions_limit(&self) -> usize;

Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ fn can_mine() {
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
let client = client_result.reference();

let b = client.prepare_open_block(Address::default(), 31415926.into(), vec![]).close();
let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).close();

assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3());
}
2 changes: 1 addition & 1 deletion ethcore/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_numbe
last_hashes.clone(),
None,
author.clone(),
3141562.into(),
(3141562.into(), 31415620.into()),
vec![]
).unwrap();
b.set_difficulty(U256::from(0x20000));
Expand Down
3 changes: 3 additions & 0 deletions parity/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ Sealing/Mining Options:
good value [default: auto].
--gas-floor-target GAS Amount of gas per block to target when sealing a new
block [default: 3141592].
--gas-cap GAS A cap on how large we will raise the gas limit per
block due to transaction volume [default: 3141592].
--author ADDRESS Specify the block author (aka "coinbase") address
for sending block rewards from sealed blocks
[default: 0037a6b811ffeb6e072da21179d11b1406371c63].
Expand Down Expand Up @@ -283,6 +285,7 @@ pub struct Args {
pub flag_usd_per_tx: String,
pub flag_usd_per_eth: String,
pub flag_gas_floor_target: String,
pub flag_gas_cap: String,
pub flag_extra_data: Option<String>,
pub flag_tx_limit: usize,
pub flag_logging: Option<String>,
Expand Down
11 changes: 10 additions & 1 deletion parity/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,16 @@ impl Configuration {
}
}


pub fn gas_ceil_target(&self) -> U256 {
if self.args.flag_dont_help_rescue_dao || self.args.flag_dogmatic {
10_000_000.into()
} else {
let d = &self.args.flag_gas_cap;
U256::from_dec_str(d).unwrap_or_else(|_| {
die!("{}: Invalid target gas ceiling given. Must be a decimal unsigned 256-bit number.", d)
})
}
}

pub fn gas_price(&self) -> U256 {
match self.args.flag_gasprice.as_ref() {
Expand Down
1 change: 1 addition & 0 deletions parity/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
let miner = Miner::with_accounts(conf.args.flag_force_sealing, conf.spec(), account_service.clone());
miner.set_author(conf.author());
miner.set_gas_floor_target(conf.gas_floor_target());
miner.set_gas_ceil_target(conf.gas_ceil_target());
miner.set_extra_data(conf.extra_data());
miner.set_minimal_gas_price(conf.gas_price());
miner.set_transactions_limit(conf.args.flag_tx_limit);
Expand Down
4 changes: 4 additions & 0 deletions rpc/src/v1/impls/ethcore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
to_value(&take_weak!(self.miner).gas_floor_target())
}

fn gas_ceil_target(&self, _: Params) -> Result<Value, Error> {
to_value(&take_weak!(self.miner).gas_ceil_target())
}

fn dev_logs(&self, _params: Params) -> Result<Value, Error> {
let logs = self.logger.logs();
to_value(&logs.deref().as_slice())
Expand Down
11 changes: 9 additions & 2 deletions rpc/src/v1/impls/ethcore_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,15 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
}

fn set_gas_floor_target(&self, params: Params) -> Result<Value, Error> {
from_params::<(U256,)>(params).and_then(|(gas_floor_target,)| {
take_weak!(self.miner).set_gas_floor_target(gas_floor_target);
from_params::<(U256,)>(params).and_then(|(target,)| {
take_weak!(self.miner).set_gas_floor_target(target);
to_value(&true)
})
}

fn set_gas_ceil_target(&self, params: Params) -> Result<Value, Error> {
from_params::<(U256,)>(params).and_then(|(target,)| {
take_weak!(self.miner).set_gas_ceil_target(target);
to_value(&true)
})
}
Expand Down
Loading