Allow configuration of target gas limit.

This commit is contained in:
Gav Wood 2016-03-14 02:00:22 +01:00
parent 97fe4fcab4
commit f6b7884a1d
8 changed files with 40 additions and 17 deletions

View File

@ -171,7 +171,7 @@ pub struct SealedBlock {
impl<'x> OpenBlock<'x> { impl<'x> OpenBlock<'x> {
/// Create a new OpenBlock ready for transaction pushing. /// Create a new OpenBlock ready for transaction pushing.
pub fn new(engine: &'x Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, author: Address, extra_data: Bytes) -> Self { pub fn new(engine: &'x Engine, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, author: Address, gas_floor_target: U256, extra_data: Bytes) -> Self {
let mut r = OpenBlock { let mut r = OpenBlock {
block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())), block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())),
engine: engine, engine: engine,
@ -185,7 +185,7 @@ impl<'x> OpenBlock<'x> {
r.block.base.header.extra_data = extra_data; r.block.base.header.extra_data = extra_data;
r.block.base.header.note_dirty(); r.block.base.header.note_dirty();
engine.populate_from_parent(&mut r.block.base.header, parent); engine.populate_from_parent(&mut r.block.base.header, parent, gas_floor_target);
engine.on_new_block(&mut r.block); engine.on_new_block(&mut r.block);
r r
} }
@ -347,7 +347,7 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head
} }
} }
let mut b = OpenBlock::new(engine, db, parent, last_hashes, header.author().clone(), header.extra_data().clone()); let mut b = OpenBlock::new(engine, db, parent, last_hashes, header.author().clone(), x!(3141562), header.extra_data().clone());
b.set_difficulty(*header.difficulty()); b.set_difficulty(*header.difficulty());
b.set_gas_limit(*header.gas_limit()); b.set_gas_limit(*header.gas_limit());
b.set_timestamp(header.timestamp()); b.set_timestamp(header.timestamp());
@ -391,7 +391,7 @@ mod tests {
let mut db = db_result.take(); let mut db = db_result.take();
engine.spec().ensure_db_good(db.as_hashdb_mut()); engine.spec().ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()]; let last_hashes = vec![genesis_header.hash()];
let b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), vec![]); let b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
let b = b.close(); let b = b.close();
let _ = b.seal(engine.deref(), vec![]); let _ = b.seal(engine.deref(), vec![]);
} }
@ -405,7 +405,7 @@ mod tests {
let mut db_result = get_temp_journal_db(); let mut db_result = get_temp_journal_db();
let mut db = db_result.take(); let mut db = db_result.take();
engine.spec().ensure_db_good(db.as_hashdb_mut()); engine.spec().ensure_db_good(db.as_hashdb_mut());
let b = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()], Address::zero(), vec![]).close().seal(engine.deref(), vec![]).unwrap(); let b = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]).close().seal(engine.deref(), vec![]).unwrap();
let orig_bytes = b.rlp_bytes(); let orig_bytes = b.rlp_bytes();
let orig_db = b.drain(); let orig_db = b.drain();

View File

@ -380,15 +380,13 @@ impl<V> Client<V> where V: Verifier {
} }
impl<V> BlockChainClient for Client<V> where V: Verifier { impl<V> BlockChainClient for Client<V> where V: Verifier {
// TODO [todr] Should be moved to miner crate eventually. // TODO [todr] Should be moved to miner crate eventually.
fn try_seal(&self, block: ClosedBlock, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> { fn try_seal(&self, block: ClosedBlock, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
block.try_seal(self.engine.deref().deref(), seal) block.try_seal(self.engine.deref().deref(), seal)
} }
// TODO [todr] Should be moved to miner crate eventually. // TODO [todr] Should be moved to miner crate eventually.
fn prepare_sealing(&self, author: Address, extra_data: Bytes, transactions: Vec<SignedTransaction>) -> Option<ClosedBlock> { fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>) -> Option<ClosedBlock> {
let engine = self.engine.deref().deref(); let engine = self.engine.deref().deref();
let h = self.chain.best_block_hash(); let h = self.chain.best_block_hash();
@ -398,6 +396,7 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
match self.chain.block_header(&h) { Some(ref x) => x, None => {return None} }, match self.chain.block_header(&h) { Some(ref x) => x, None => {return None} },
self.build_last_hashes(h.clone()), self.build_last_hashes(h.clone()),
author, author,
gas_floor_target,
extra_data, extra_data,
); );

View File

@ -110,7 +110,7 @@ pub trait BlockChainClient : Sync + Send {
// TODO [todr] Should be moved to miner crate eventually. // TODO [todr] Should be moved to miner crate eventually.
/// Returns ClosedBlock prepared for sealing. /// Returns ClosedBlock prepared for sealing.
fn prepare_sealing(&self, author: Address, extra_data: Bytes, transactions: Vec<SignedTransaction>) -> Option<ClosedBlock>; fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>) -> Option<ClosedBlock>;
// TODO [todr] Should be moved to miner crate eventually. // TODO [todr] Should be moved to miner crate eventually.
/// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error. /// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error.

View File

@ -215,7 +215,7 @@ impl BlockChainClient for TestBlockChainClient {
unimplemented!(); unimplemented!();
} }
fn prepare_sealing(&self, _author: Address, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<ClosedBlock> { fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<ClosedBlock> {
unimplemented!() unimplemented!()
} }

View File

@ -85,7 +85,7 @@ pub trait Engine : Sync + Send {
/// Don't forget to call Super::populate_from_parent when subclassing & overriding. /// Don't forget to call Super::populate_from_parent when subclassing & overriding.
// TODO: consider including State in the params. // TODO: consider including State in the params.
fn populate_from_parent(&self, header: &mut Header, parent: &Header) { fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256) {
header.difficulty = parent.difficulty; header.difficulty = parent.difficulty;
header.gas_limit = parent.gas_limit; header.gas_limit = parent.gas_limit;
header.note_dirty(); header.note_dirty();

View File

@ -92,10 +92,9 @@ impl Engine for Ethash {
} }
} }
fn populate_from_parent(&self, header: &mut Header, parent: &Header) { fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256) {
header.difficulty = self.calculate_difficuty(header, parent); header.difficulty = self.calculate_difficuty(header, parent);
header.gas_limit = { header.gas_limit = {
let gas_floor_target: U256 = x!(3141562);
let gas_limit = parent.gas_limit; let gas_limit = parent.gas_limit;
let bound_divisor = self.u256_param("gasLimitBoundDivisor"); let bound_divisor = self.u256_param("gasLimitBoundDivisor");
if gas_limit < gas_floor_target { if gas_limit < gas_floor_target {
@ -300,7 +299,7 @@ mod tests {
let mut db = db_result.take(); let mut db = db_result.take();
engine.spec().ensure_db_good(db.as_hashdb_mut()); engine.spec().ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()]; let last_hashes = vec![genesis_header.hash()];
let b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), vec![]); let b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
let b = b.close(); let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
} }
@ -313,7 +312,7 @@ mod tests {
let mut db = db_result.take(); let mut db = db_result.take();
engine.spec().ensure_db_good(db.as_hashdb_mut()); engine.spec().ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()]; let last_hashes = vec![genesis_header.hash()];
let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), vec![]); let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
let mut uncle = Header::new(); let mut uncle = Header::new();
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
uncle.author = uncle_author.clone(); uncle.author = uncle_author.clone();

View File

@ -19,7 +19,7 @@ use std::sync::{Mutex, RwLock, Arc};
use std::sync::atomic; use std::sync::atomic;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use util::{H256, U256, Address, Bytes}; use util::{H256, U256, Address, Bytes, Uint};
use ethcore::views::{BlockView}; use ethcore::views::{BlockView};
use ethcore::client::{BlockChainClient, BlockId}; use ethcore::client::{BlockChainClient, BlockId};
use ethcore::block::{ClosedBlock}; use ethcore::block::{ClosedBlock};
@ -34,8 +34,10 @@ pub struct Miner {
// for sealing... // for sealing...
sealing_enabled: AtomicBool, sealing_enabled: AtomicBool,
sealing_block: Mutex<Option<ClosedBlock>>, sealing_block: Mutex<Option<ClosedBlock>>,
gas_floor_target: RwLock<U256>,
author: RwLock<Address>, author: RwLock<Address>,
extra_data: RwLock<Bytes>, extra_data: RwLock<Bytes>,
} }
impl Default for Miner { impl Default for Miner {
@ -44,6 +46,7 @@ impl Default for Miner {
transaction_queue: Mutex::new(TransactionQueue::new()), transaction_queue: Mutex::new(TransactionQueue::new()),
sealing_enabled: AtomicBool::new(false), sealing_enabled: AtomicBool::new(false),
sealing_block: Mutex::new(None), sealing_block: Mutex::new(None),
gas_floor_target: RwLock::new(U256::zero()),
author: RwLock::new(Address::default()), author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()), extra_data: RwLock::new(Vec::new()),
} }
@ -66,6 +69,11 @@ impl Miner {
self.extra_data.read().unwrap().clone() self.extra_data.read().unwrap().clone()
} }
/// Get the extra_data that we will seal blocks wuth.
fn gas_floor_target(&self) -> U256 {
self.gas_floor_target.read().unwrap().clone()
}
/// Set the author that we will seal blocks as. /// Set the author that we will seal blocks as.
pub fn set_author(&self, author: Address) { pub fn set_author(&self, author: Address) {
*self.author.write().unwrap() = author; *self.author.write().unwrap() = author;
@ -76,6 +84,11 @@ impl Miner {
*self.extra_data.write().unwrap() = extra_data; *self.extra_data.write().unwrap() = extra_data;
} }
/// Set the gas limit we wish to target when sealing a new block.
pub fn set_gas_floor_target(&self, target: U256) {
*self.gas_floor_target.write().unwrap() = target;
}
/// Set minimal gas price of transaction to be accepted for mining. /// Set minimal gas price of transaction to be accepted for mining.
pub fn set_minimal_gas_price(&self, min_gas_price: U256) { pub fn set_minimal_gas_price(&self, min_gas_price: U256) {
self.transaction_queue.lock().unwrap().set_minimal_gas_price(min_gas_price); self.transaction_queue.lock().unwrap().set_minimal_gas_price(min_gas_price);
@ -110,12 +123,14 @@ impl MinerService for Miner {
fn prepare_sealing(&self, chain: &BlockChainClient) { fn prepare_sealing(&self, chain: &BlockChainClient) {
let no_of_transactions = 128; let no_of_transactions = 128;
// TODO: should select transactions orm queue according to gas limit of block.
let transactions = self.transaction_queue.lock().unwrap().top_transactions(no_of_transactions); let transactions = self.transaction_queue.lock().unwrap().top_transactions(no_of_transactions);
let b = chain.prepare_sealing( let b = chain.prepare_sealing(
self.author(), self.author(),
self.gas_floor_target(),
self.extra_data(), self.extra_data(),
transactions, transactions
); );
*self.sealing_block.lock().unwrap() = b; *self.sealing_block.lock().unwrap() = b;
} }

View File

@ -115,6 +115,7 @@ API and Console Options:
Sealing/Mining Options: Sealing/Mining Options:
--gas-price WEI Minimum amount of Wei to be paid for a transaction to be accepted for mining [default: 20000000000]. --gas-price WEI Minimum amount of Wei to be paid for a transaction to be accepted for mining [default: 20000000000].
--gas-floor-target GAS Amount of gas per block to target when sealing a new block [default: 4712388].
--author ADDRESS Specify the block author (aka "coinbase") address for sending block rewards --author ADDRESS Specify the block author (aka "coinbase") address for sending block rewards
from sealed blocks [default: 0037a6b811ffeb6e072da21179d11b1406371c63]. from sealed blocks [default: 0037a6b811ffeb6e072da21179d11b1406371c63].
--extra-data STRING Specify a custom extra-data for authored blocks, no more than 32 characters. --extra-data STRING Specify a custom extra-data for authored blocks, no more than 32 characters.
@ -178,6 +179,7 @@ struct Args {
flag_jsonrpc_apis: String, flag_jsonrpc_apis: String,
flag_author: String, flag_author: String,
flag_gas_price: String, flag_gas_price: String,
flag_gas_floor_target: String,
flag_extra_data: Option<String>, flag_extra_data: Option<String>,
flag_logging: Option<String>, flag_logging: Option<String>,
flag_version: bool, flag_version: bool,
@ -303,6 +305,13 @@ impl Configuration {
}) })
} }
fn gas_floor_target(&self) -> U256 {
let d = &self.args.flag_gas_floor_target;
U256::from_dec_str(d).unwrap_or_else(|_| {
die!("{}: Invalid target gas floor given. Must be a decimal unsigned 256-bit number.", d)
})
}
fn gas_price(&self) -> U256 { fn gas_price(&self) -> U256 {
let d = self.args.flag_gasprice.as_ref().unwrap_or(&self.args.flag_gas_price); let d = self.args.flag_gasprice.as_ref().unwrap_or(&self.args.flag_gas_price);
U256::from_dec_str(d).unwrap_or_else(|_| { U256::from_dec_str(d).unwrap_or_else(|_| {
@ -485,6 +494,7 @@ impl Configuration {
// Miner // Miner
let miner = Miner::new(); let miner = Miner::new();
miner.set_author(self.author()); miner.set_author(self.author());
miner.set_gas_floor_target(self.gas_floor_target());
miner.set_extra_data(self.extra_data()); miner.set_extra_data(self.extra_data());
miner.set_minimal_gas_price(self.gas_price()); miner.set_minimal_gas_price(self.gas_price());