diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 22e61ab09..06c3054a9 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -242,7 +242,7 @@ impl TestBlockChainClient { value: U256::from(100), data: "3331600055".from_hex().unwrap(), gas: U256::from(100_000), - gas_price: U256::one(), + gas_price: U256::from(200_000_000_000u64), nonce: U256::zero() }; let signed_tx = tx.sign(keypair.secret(), None); @@ -308,11 +308,11 @@ impl TestBlockChainClient { value: U256::from(100), data: "3331600055".from_hex().unwrap(), gas: U256::from(100_000), - gas_price: U256::one(), + gas_price: U256::from(20_000_000_000u64), nonce: U256::zero() }; let signed_tx = tx.sign(keypair.secret(), None); - self.set_balance(signed_tx.sender().unwrap(), 10_000_000.into()); + self.set_balance(signed_tx.sender().unwrap(), 10_000_000_000_000_000_000u64.into()); let res = self.miner.import_external_transactions(self, vec![signed_tx]); let res = res.into_iter().next().unwrap().expect("Successful import"); assert_eq!(res, TransactionImportResult::Current); diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index d5b3b00b6..2f1e80058 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -304,16 +304,6 @@ impl Miner { #[cfg_attr(feature="dev", allow(match_same_arms))] /// Prepares new block for sealing including top transactions from queue. fn prepare_block(&self, chain: &MiningBlockChainClient) -> (ClosedBlock, Option) { - { - trace!(target: "miner", "prepare_block: recalibrating..."); - let txq = self.transaction_queue.clone(); - self.gas_pricer.lock().recalibrate(move |price| { - trace!(target: "miner", "prepare_block: Got gas price! {}", price); - txq.lock().set_minimal_gas_price(price); - }); - trace!(target: "miner", "prepare_block: done recalibration."); - } - let _timer = PerfTimer::new("prepare_block"); let chain_info = chain.chain_info(); let (transactions, mut open_block, original_work_hash) = { @@ -428,6 +418,16 @@ impl Miner { (block, original_work_hash) } + /// Asynchronously updates minimal gas price for transaction queue + pub fn recalibrate_minimal_gas_price(&self) { + debug!(target: "miner", "minimal_gas_price: recalibrating..."); + let txq = self.transaction_queue.clone(); + self.gas_pricer.lock().recalibrate(move |price| { + debug!(target: "miner", "minimal_gas_price: Got gas price! {}", price); + txq.lock().set_minimal_gas_price(price); + }); + } + /// Check is reseal is allowed and necessary. fn requires_reseal(&self, best_block: BlockNumber) -> bool { let has_local_transactions = self.transaction_queue.lock().has_local_pending_transactions(); @@ -1121,6 +1121,9 @@ impl MinerService for Miner { // First update gas limit in transaction queue self.update_gas_limit(chain); + // Update minimal gas price + self.recalibrate_minimal_gas_price(); + // Then import all transactions... { retracted.par_iter() diff --git a/parity/configuration.rs b/parity/configuration.rs index 9a0b8d831..6d23579c1 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -532,22 +532,32 @@ impl Configuration { } fn gas_pricer_config(&self) -> Result { + fn wei_per_gas(usd_per_tx: f32, usd_per_eth: f32) -> U256 { + let wei_per_usd: f32 = 1.0e18 / usd_per_eth; + let gas_per_tx: f32 = 21000.0; + let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx; + U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap() + } + if let Some(d) = self.args.flag_gasprice.as_ref() { return Ok(GasPricerConfig::Fixed(to_u256(d)?)); } let usd_per_tx = to_price(&self.args.flag_usd_per_tx)?; if "auto" == self.args.flag_usd_per_eth.as_str() { + // Just a very rough estimate to avoid accepting + // ZGP transactions before the price is fetched + // if user does not want it. + let last_known_usd_per_eth = 10.0; return Ok(GasPricerConfig::Calibrated { + initial_minimum: wei_per_gas(usd_per_tx, last_known_usd_per_eth), usd_per_tx: usd_per_tx, recalibration_period: to_duration(self.args.flag_price_update_period.as_str())?, }); } let usd_per_eth = to_price(&self.args.flag_usd_per_eth)?; - let wei_per_usd: f32 = 1.0e18 / usd_per_eth; - let gas_per_tx: f32 = 21000.0; - let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx; + let wei_per_gas = wei_per_gas(usd_per_tx, usd_per_eth); info!( "Using a fixed conversion rate of Ξ1 = {} ({} wei/gas)", @@ -555,7 +565,7 @@ impl Configuration { Colour::Yellow.bold().paint(format!("{}", wei_per_gas)) ); - Ok(GasPricerConfig::Fixed(U256::from_dec_str(&format!("{:.0}", wei_per_gas)).unwrap())) + Ok(GasPricerConfig::Fixed(wei_per_gas)) } fn extra_data(&self) -> Result { diff --git a/parity/params.rs b/parity/params.rs index 93d109979..7ef806fb8 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -192,14 +192,25 @@ impl Default for AccountsConfig { pub enum GasPricerConfig { Fixed(U256), Calibrated { + initial_minimum: U256, usd_per_tx: f32, recalibration_period: Duration, } } +impl GasPricerConfig { + pub fn initial_min(&self) -> U256 { + match *self { + GasPricerConfig::Fixed(ref min) => min.clone(), + GasPricerConfig::Calibrated { ref initial_minimum, .. } => initial_minimum.clone(), + } + } +} + impl Default for GasPricerConfig { fn default() -> Self { GasPricerConfig::Calibrated { + initial_minimum: 11904761856u64.into(), usd_per_tx: 0.0025f32, recalibration_period: Duration::from_secs(3600), } @@ -210,7 +221,7 @@ impl Into for GasPricerConfig { fn into(self) -> GasPricer { match self { GasPricerConfig::Fixed(u) => GasPricer::Fixed(u), - GasPricerConfig::Calibrated { usd_per_tx, recalibration_period } => { + GasPricerConfig::Calibrated { usd_per_tx, recalibration_period, .. } => { GasPricer::new_calibrated(GasPriceCalibratorOptions { usd_per_tx: usd_per_tx, recalibration_period: recalibration_period, diff --git a/parity/run.rs b/parity/run.rs index e4c5fca6f..b04118c75 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -236,12 +236,15 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> R spec.engine.register_account_provider(account_provider.clone()); // create miner + let initial_min_gas_price = cmd.gas_pricer.initial_min(); let miner = Miner::new(cmd.miner_options, cmd.gas_pricer.into(), &spec, Some(account_provider.clone())); miner.set_author(cmd.miner_extras.author); miner.set_gas_floor_target(cmd.miner_extras.gas_floor_target); miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target); miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); + miner.set_minimal_gas_price(initial_min_gas_price); + miner.recalibrate_minimal_gas_price(); let engine_signer = cmd.miner_extras.engine_signer; if engine_signer != Default::default() { diff --git a/sync/src/chain.rs b/sync/src/chain.rs index d36cc26c9..f3ab5f3b3 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -2775,7 +2775,7 @@ mod tests { // Add some balance to clients and reset nonces for h in &[good_blocks[0], retracted_blocks[0]] { let block = client.block(BlockId::Hash(*h)).unwrap(); - client.set_balance(block.transactions()[0].sender().unwrap(), U256::from(1_000_000_000)); + client.set_balance(block.transactions()[0].sender().unwrap(), U256::from(10_000_000_000_000_000_000u64)); client.set_nonce(block.transactions()[0].sender().unwrap(), U256::from(0)); }