Gas price statistics. (#1291)

* Gas price statistics.

Affects eth_gasPrice.
Added ethcore_gasPriceStatistics.

Closes #1265

* Fix a bug in eth_gasPrice

* Fix tests.

* Revert minor alteration.

* Tests for gas_price_statistics.

- Tests;
- Additional infrastructure for generating test blocks with
transactions.
This commit is contained in:
Gav Wood
2016-06-16 12:44:08 +02:00
committed by arkpar
parent 6026dd3657
commit 335bce85e8
12 changed files with 225 additions and 52 deletions

View File

@@ -770,8 +770,7 @@ impl<V> MiningBlockChainClient for Client<V> where V: Verifier {
author,
gas_floor_target,
extra_data,
).expect("OpenBlock::new only fails if parent state root invalid. State root of best block's header is never invalid. \
Therefore creating an OpenBlock with the best block's header will not fail.");
).expect("OpenBlock::new only fails if parent state root invalid; state root of best block's header is never invalid; qed");
// Add uncles
self.chain

View File

@@ -34,6 +34,7 @@ pub use env_info::{LastHashes, EnvInfo};
use util::bytes::Bytes;
use util::hash::{Address, H256, H2048};
use util::numbers::U256;
use util::Itertools;
use blockchain::TreeRoute;
use block_queue::BlockQueueInfo;
use block::OpenBlock;
@@ -41,6 +42,7 @@ use header::{BlockNumber, Header};
use transaction::{LocalizedTransaction, SignedTransaction};
use log_entry::LocalizedLogEntry;
use filter::Filter;
use views::BlockView;
use error::{ImportResult, ExecutionError};
use receipt::LocalizedReceipt;
use trace::LocalizedTrace;
@@ -193,6 +195,32 @@ pub trait BlockChainClient : Sync + Send {
/// list all transactions
fn all_transactions(&self) -> Vec<SignedTransaction>;
/// Get the gas price distribution.
fn gas_price_statistics(&self, sample_size: usize, distribution_size: usize) -> Result<Vec<U256>, ()> {
let mut h = self.chain_info().best_block_hash;
let mut corpus = Vec::new();
for _ in 0..sample_size {
let block_bytes = self.block(BlockID::Hash(h)).expect("h is either the best_block_hash or an ancestor; qed");
let block = BlockView::new(&block_bytes);
let header = block.header_view();
if header.number() == 0 {
break;
}
block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price()));
h = header.parent_hash().clone();
}
corpus.sort();
let n = corpus.len();
if n > 0 {
Ok((0..(distribution_size + 1))
.map(|i| corpus[i * (n - 1) / distribution_size])
.collect::<Vec<_>>()
)
} else {
Err(())
}
}
}
/// Extended client interface used for mining