fetch gas price corpus from network when needed
This commit is contained in:
@@ -23,6 +23,7 @@ smallvec = "0.3.1"
|
||||
futures = "0.1"
|
||||
rand = "0.3"
|
||||
itertools = "0.5"
|
||||
stats = { path = "../../util/stats" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -24,6 +24,7 @@ use ethcore::encoded;
|
||||
use ethcore::header::BlockNumber;
|
||||
use ethcore::receipt::Receipt;
|
||||
|
||||
use stats::Corpus;
|
||||
use time::{SteadyTime, Duration};
|
||||
use util::{U256, H256};
|
||||
use util::cache::MemoryLruCache;
|
||||
@@ -66,7 +67,7 @@ pub struct Cache {
|
||||
bodies: MemoryLruCache<H256, encoded::Body>,
|
||||
receipts: MemoryLruCache<H256, Vec<Receipt>>,
|
||||
chain_score: MemoryLruCache<H256, U256>,
|
||||
corpus: Option<(Vec<U256>, SteadyTime)>,
|
||||
corpus: Option<(Corpus<U256>, SteadyTime)>,
|
||||
corpus_expiration: Duration,
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ impl Cache {
|
||||
}
|
||||
|
||||
/// Get gas price corpus, if recent enough.
|
||||
pub fn gas_price_corpus(&self) -> Option<Vec<U256>> {
|
||||
pub fn gas_price_corpus(&self) -> Option<Corpus<U256>> {
|
||||
let now = SteadyTime::now();
|
||||
|
||||
self.corpus.as_ref().and_then(|&(ref corpus, ref tm)| {
|
||||
@@ -148,7 +149,7 @@ impl Cache {
|
||||
}
|
||||
|
||||
/// Set the cached gas price corpus.
|
||||
pub fn set_gas_price_corpus(&mut self, corpus: Vec<U256>) {
|
||||
pub fn set_gas_price_corpus(&mut self, corpus: Corpus<U256>) {
|
||||
self.corpus = Some((corpus, SteadyTime::now()))
|
||||
}
|
||||
}
|
||||
@@ -162,8 +163,8 @@ mod tests {
|
||||
fn corpus_inaccessible() {
|
||||
let mut cache = Cache::new(Default::default(), Duration::hours(5));
|
||||
|
||||
cache.set_gas_price_corpus(vec![]);
|
||||
assert_eq!(cache.gas_price_corpus(), Some(vec![]));
|
||||
cache.set_gas_price_corpus(vec![].into());
|
||||
assert_eq!(cache.gas_price_corpus(), Some(vec![].into()));
|
||||
|
||||
{
|
||||
let corpus_time = &mut cache.corpus.as_mut().unwrap().1;
|
||||
|
||||
@@ -241,6 +241,14 @@ impl HeaderChain {
|
||||
self.block_header(BlockId::Latest).expect("Header for best block always stored; qed")
|
||||
}
|
||||
|
||||
/// Get an iterator over a block and its ancestry.
|
||||
pub fn ancestry_iter(&self, start: BlockId) -> AncestryIter {
|
||||
AncestryIter {
|
||||
next: self.block_header(start),
|
||||
chain: self,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the nth CHT root, if it's been computed.
|
||||
///
|
||||
/// CHT root 0 is from block `1..2048`.
|
||||
@@ -295,6 +303,25 @@ impl HeapSizeOf for HeaderChain {
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator over a block's ancestry.
|
||||
pub struct AncestryIter<'a> {
|
||||
next: Option<encoded::Header>,
|
||||
chain: &'a HeaderChain,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for AncestryIter<'a> {
|
||||
type Item = encoded::Header;
|
||||
|
||||
fn next(&mut self) -> Option<encoded::Header> {
|
||||
let next = self.next.take();
|
||||
if let Some(p_hash) = next.as_ref().map(|hdr| hdr.parent_hash()) {
|
||||
self.next = self.chain.block_header(BlockId::Hash(p_hash));
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::HeaderChain;
|
||||
|
||||
@@ -33,7 +33,7 @@ use io::IoChannel;
|
||||
|
||||
use util::{Bytes, H256, Mutex, RwLock};
|
||||
|
||||
use self::header_chain::HeaderChain;
|
||||
use self::header_chain::{AncestryIter, HeaderChain};
|
||||
|
||||
pub use self::service::Service;
|
||||
|
||||
@@ -62,6 +62,9 @@ pub trait LightChainClient: Send + Sync {
|
||||
/// Get the best block header.
|
||||
fn best_block_header(&self) -> encoded::Header;
|
||||
|
||||
/// Get an iterator over a block and its ancestry.
|
||||
fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a>;
|
||||
|
||||
/// Get the signing network ID.
|
||||
fn signing_network_id(&self) -> Option<u64>;
|
||||
|
||||
@@ -167,6 +170,11 @@ impl Client {
|
||||
self.chain.best_header()
|
||||
}
|
||||
|
||||
/// Get an iterator over a block and its ancestry.
|
||||
pub fn ancestry_iter(&self, start: BlockId) -> AncestryIter {
|
||||
self.chain.ancestry_iter(start)
|
||||
}
|
||||
|
||||
/// Get the signing network id.
|
||||
pub fn signing_network_id(&self) -> Option<u64> {
|
||||
self.engine.signing_network_id(&self.latest_env_info())
|
||||
@@ -269,6 +277,10 @@ impl LightChainClient for Client {
|
||||
Client::best_block_header(self)
|
||||
}
|
||||
|
||||
fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a> {
|
||||
Box::new(Client::ancestry_iter(self, start))
|
||||
}
|
||||
|
||||
fn signing_network_id(&self) -> Option<u64> {
|
||||
Client::signing_network_id(self)
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ extern crate time;
|
||||
extern crate futures;
|
||||
extern crate rand;
|
||||
extern crate itertools;
|
||||
extern crate stats;
|
||||
|
||||
#[cfg(feature = "ipc")]
|
||||
extern crate ethcore_ipc as ipc;
|
||||
|
||||
Reference in New Issue
Block a user