Merge pull request #719 from ethcore/targetgaslimit
Allow configuration of target gas limit.
This commit is contained in:
commit
38de95cc3b
@ -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();
|
||||||
|
|
||||||
|
@ -109,6 +109,11 @@ pub struct Client<V = CanonVerifier> where V: Verifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const HISTORY: u64 = 1000;
|
const HISTORY: u64 = 1000;
|
||||||
|
// DO NOT TOUCH THIS ANY MORE UNLESS YOU REALLY KNOW WHAT YOU'RE DOING.
|
||||||
|
// Altering it will force a blanket DB update for *all* JournalDB-derived
|
||||||
|
// databases.
|
||||||
|
// Instead, add/upgrade the version string of the individual JournalDB-derived database
|
||||||
|
// of which you actually want force an upgrade.
|
||||||
const CLIENT_DB_VER_STR: &'static str = "5.2";
|
const CLIENT_DB_VER_STR: &'static str = "5.2";
|
||||||
|
|
||||||
impl Client<CanonVerifier> {
|
impl Client<CanonVerifier> {
|
||||||
@ -380,15 +385,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 +401,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,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -133,7 +133,7 @@ fn can_mine() {
|
|||||||
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
|
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
|
|
||||||
let b = client.prepare_sealing(Address::default(), vec![], vec![]).unwrap();
|
let b = client.prepare_sealing(Address::default(), x!(31415926), vec![], vec![]).unwrap();
|
||||||
|
|
||||||
assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3());
|
assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3());
|
||||||
assert!(client.try_seal(b, vec![]).is_ok());
|
assert!(client.try_seal(b, vec![]).is_ok());
|
||||||
|
@ -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,10 +123,12 @@ 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,
|
||||||
);
|
);
|
||||||
|
@ -119,6 +119,8 @@ API and Console Options:
|
|||||||
Sealing/Mining Options:
|
Sealing/Mining Options:
|
||||||
--gas-price WEI Minimum amount of Wei to be paid for a transaction
|
--gas-price WEI Minimum amount of Wei to be paid for a transaction
|
||||||
to be accepted for mining [default: 20000000000].
|
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
|
--author ADDRESS Specify the block author (aka "coinbase") address
|
||||||
for sending block rewards from sealed blocks
|
for sending block rewards from sealed blocks
|
||||||
[default: 0037a6b811ffeb6e072da21179d11b1406371c63].
|
[default: 0037a6b811ffeb6e072da21179d11b1406371c63].
|
||||||
@ -192,6 +194,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,
|
||||||
@ -317,6 +320,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(|_| {
|
||||||
@ -499,6 +509,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());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user