perf(ethcore): micro-opt (#10405)

Mostly fixes that changes `eagerly eval` to `lazy eval`
This commit is contained in:
Niklas Adolfsson 2019-03-06 15:30:35 +01:00 committed by Marek Kotewicz
parent 3e1d73126c
commit 91933d857d
15 changed files with 39 additions and 35 deletions

View File

@ -24,7 +24,6 @@ use std::marker::PhantomData;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use ethcore::executed::{Executed, ExecutionError};
use futures::{Poll, Future, Async}; use futures::{Poll, Future, Async};
use futures::sync::oneshot::{self, Receiver}; use futures::sync::oneshot::{self, Receiver};
use network::PeerId; use network::PeerId;
@ -41,10 +40,10 @@ use cache::Cache;
use request::{self as basic_request, Request as NetworkRequest}; use request::{self as basic_request, Request as NetworkRequest};
use self::request::CheckedRequest; use self::request::CheckedRequest;
pub use ethcore::executed::ExecutionResult;
pub use self::request::{Request, Response, HeaderRef, Error as ValidityError}; pub use self::request::{Request, Response, HeaderRef, Error as ValidityError};
pub use self::request_guard::{RequestGuard, Error as RequestError}; pub use self::request_guard::{RequestGuard, Error as RequestError};
pub use self::response_guard::{ResponseGuard, Error as ResponseGuardError, Inner as ResponseGuardInner}; pub use self::response_guard::{ResponseGuard, Error as ResponseGuardError, Inner as ResponseGuardInner};
pub use types::request::ResponseError; pub use types::request::ResponseError;
#[cfg(test)] #[cfg(test)]
@ -54,9 +53,6 @@ pub mod request;
mod request_guard; mod request_guard;
mod response_guard; mod response_guard;
/// The result of execution
pub type ExecutionResult = Result<Executed, ExecutionError>;
/// The initial backoff interval for OnDemand queries /// The initial backoff interval for OnDemand queries
pub const DEFAULT_REQUEST_MIN_BACKOFF_DURATION: Duration = Duration::from_secs(10); pub const DEFAULT_REQUEST_MIN_BACKOFF_DURATION: Duration = Duration::from_secs(10);
/// The maximum request interval for OnDemand queries /// The maximum request interval for OnDemand queries

View File

@ -1149,7 +1149,7 @@ impl Client {
pub fn take_snapshot<W: snapshot_io::SnapshotWriter + Send>(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> { pub fn take_snapshot<W: snapshot_io::SnapshotWriter + Send>(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> {
let db = self.state_db.read().journal_db().boxed_clone(); let db = self.state_db.read().journal_db().boxed_clone();
let best_block_number = self.chain_info().best_block_number; let best_block_number = self.chain_info().best_block_number;
let block_number = self.block_number(at).ok_or(snapshot::Error::InvalidStartingBlock(at))?; let block_number = self.block_number(at).ok_or_else(|| snapshot::Error::InvalidStartingBlock(at))?;
if db.is_pruned() && self.pruning_info().earliest_state > block_number { if db.is_pruned() && self.pruning_info().earliest_state > block_number {
return Err(snapshot::Error::OldBlockPrunedDB.into()); return Err(snapshot::Error::OldBlockPrunedDB.into());

View File

@ -512,15 +512,19 @@ fn header_expected_seal_fields(header: &Header, empty_steps_transition: u64) ->
} }
fn header_step(header: &Header, empty_steps_transition: u64) -> Result<u64, ::rlp::DecoderError> { fn header_step(header: &Header, empty_steps_transition: u64) -> Result<u64, ::rlp::DecoderError> {
let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition); Rlp::new(&header.seal().get(0).unwrap_or_else(||
Rlp::new(&header.seal().get(0).expect( panic!("was either checked with verify_block_basic or is genesis; has {} fields; qed (Make sure the spec
&format!("was either checked with verify_block_basic or is genesis; has {} fields; qed (Make sure the spec file has a correct genesis seal)", expected_seal_fields))).as_val() file has a correct genesis seal)", header_expected_seal_fields(header, empty_steps_transition))
))
.as_val()
} }
fn header_signature(header: &Header, empty_steps_transition: u64) -> Result<Signature, ::rlp::DecoderError> { fn header_signature(header: &Header, empty_steps_transition: u64) -> Result<Signature, ::rlp::DecoderError> {
let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition); Rlp::new(&header.seal().get(1).unwrap_or_else(||
Rlp::new(&header.seal().get(1).expect( panic!("was checked with verify_block_basic; has {} fields; qed",
&format!("was checked with verify_block_basic; has {} fields; qed", expected_seal_fields))).as_val::<H520>().map(Into::into) header_expected_seal_fields(header, empty_steps_transition))
))
.as_val::<H520>().map(Into::into)
} }
// extracts the raw empty steps vec from the header seal. should only be called when there are 3 fields in the seal // extracts the raw empty steps vec from the header seal. should only be called when there are 3 fields in the seal
@ -934,8 +938,12 @@ impl Engine<EthereumMachine> for AuthorityRound {
return BTreeMap::default(); return BTreeMap::default();
} }
let step = header_step(header, self.empty_steps_transition).as_ref().map(ToString::to_string).unwrap_or("".into()); let step = header_step(header, self.empty_steps_transition).as_ref()
let signature = header_signature(header, self.empty_steps_transition).as_ref().map(ToString::to_string).unwrap_or("".into()); .map(ToString::to_string)
.unwrap_or_default();
let signature = header_signature(header, self.empty_steps_transition).as_ref()
.map(ToString::to_string)
.unwrap_or_default();
let mut info = map![ let mut info = map![
"step".into() => step, "step".into() => step,

View File

@ -74,7 +74,7 @@ impl Multi {
impl ValidatorSet for Multi { impl ValidatorSet for Multi {
fn default_caller(&self, block_id: BlockId) -> Box<Call> { fn default_caller(&self, block_id: BlockId) -> Box<Call> {
self.correct_set(block_id).map(|set| set.default_caller(block_id)) self.correct_set(block_id).map(|set| set.default_caller(block_id))
.unwrap_or(Box::new(|_, _| Err("No validator set for given ID.".into()))) .unwrap_or_else(|| Box::new(|_, _| Err("No validator set for given ID.".into())))
} }
fn on_epoch_begin(&self, _first: bool, header: &Header, call: &mut SystemCall) -> Result<(), ::error::Error> { fn on_epoch_begin(&self, _first: bool, header: &Header, call: &mut SystemCall) -> Result<(), ::error::Error> {
@ -141,7 +141,7 @@ impl ValidatorSet for Multi {
*self.block_number.write() = Box::new(move |id| client *self.block_number.write() = Box::new(move |id| client
.upgrade() .upgrade()
.ok_or_else(|| "No client!".into()) .ok_or_else(|| "No client!".into())
.and_then(|c| c.block_number(id).ok_or("Unknown block".into()))); .and_then(|c| c.block_number(id).ok_or_else(|| "Unknown block".into())));
} }
} }

View File

@ -37,7 +37,7 @@ use engines::EngineError;
pub use executed::{ExecutionError, CallError}; pub use executed::{ExecutionError, CallError};
#[derive(Debug, PartialEq, Clone, Copy, Eq)] #[derive(Debug, PartialEq, Clone, Eq)]
/// Errors concerning block processing. /// Errors concerning block processing.
pub enum BlockError { pub enum BlockError {
/// Block has too many uncles. /// Block has too many uncles.
@ -88,7 +88,7 @@ pub enum BlockError {
/// Timestamp header field is too far in future. /// Timestamp header field is too far in future.
TemporarilyInvalid(OutOfBounds<SystemTime>), TemporarilyInvalid(OutOfBounds<SystemTime>),
/// Log bloom header field is invalid. /// Log bloom header field is invalid.
InvalidLogBloom(Mismatch<Bloom>), InvalidLogBloom(Box<Mismatch<Bloom>>),
/// Number field of header is invalid. /// Number field of header is invalid.
InvalidNumber(Mismatch<BlockNumber>), InvalidNumber(Mismatch<BlockNumber>),
/// Block number isn't sensible. /// Block number isn't sensible.

View File

@ -197,4 +197,4 @@ impl fmt::Display for CallError {
} }
/// Transaction execution result. /// Transaction execution result.
pub type ExecutionResult = Result<Executed, ExecutionError>; pub type ExecutionResult = Result<Box<Executed>, ExecutionError>;

View File

@ -117,7 +117,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
{ {
fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> { fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> {
if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? { if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? {
self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into) self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or_default()).map_err(Into::into)
} else { } else {
warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address); warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address);
Ok(H256::zero()) Ok(H256::zero())

View File

@ -173,7 +173,7 @@ impl EthereumMachine {
origin: SYSTEM_ADDRESS, origin: SYSTEM_ADDRESS,
gas, gas,
gas_price: 0.into(), gas_price: 0.into(),
value: value.unwrap_or(ActionValue::Transfer(0.into())), value: value.unwrap_or_else(|| ActionValue::Transfer(0.into())),
code, code,
code_hash, code_hash,
data, data,

View File

@ -76,7 +76,7 @@ impl SnapshotComponents for PoaSnapshot {
} }
let header = chain.block_header_data(&transition.block_hash) let header = chain.block_header_data(&transition.block_hash)
.ok_or(Error::BlockNotFound(transition.block_hash))?; .ok_or_else(|| Error::BlockNotFound(transition.block_hash))?;
let entry = { let entry = {
let mut entry_stream = RlpStream::new_list(2); let mut entry_stream = RlpStream::new_list(2);
@ -101,12 +101,12 @@ impl SnapshotComponents for PoaSnapshot {
let (block, receipts) = chain.block(&block_at) let (block, receipts) = chain.block(&block_at)
.and_then(|b| chain.block_receipts(&block_at).map(|r| (b, r))) .and_then(|b| chain.block_receipts(&block_at).map(|r| (b, r)))
.ok_or(Error::BlockNotFound(block_at))?; .ok_or_else(|| Error::BlockNotFound(block_at))?;
let block = block.decode()?; let block = block.decode()?;
let parent_td = chain.block_details(block.header.parent_hash()) let parent_td = chain.block_details(block.header.parent_hash())
.map(|d| d.total_difficulty) .map(|d| d.total_difficulty)
.ok_or(Error::BlockNotFound(block_at))?; .ok_or_else(|| Error::BlockNotFound(block_at))?;
rlps.push({ rlps.push({
let mut stream = RlpStream::new_list(5); let mut stream = RlpStream::new_list(5);

View File

@ -116,7 +116,7 @@ impl<'a> PowWorker<'a> {
let (block, receipts) = self.chain.block(&self.current_hash) let (block, receipts) = self.chain.block(&self.current_hash)
.and_then(|b| self.chain.block_receipts(&self.current_hash).map(|r| (b, r))) .and_then(|b| self.chain.block_receipts(&self.current_hash).map(|r| (b, r)))
.ok_or(Error::BlockNotFound(self.current_hash))?; .ok_or_else(|| Error::BlockNotFound(self.current_hash))?;
let abridged_rlp = AbridgedBlock::from_block_view(&block.view()).into_inner(); let abridged_rlp = AbridgedBlock::from_block_view(&block.view()).into_inner();
@ -160,7 +160,7 @@ impl<'a> PowWorker<'a> {
let (last_header, last_details) = self.chain.block_header_data(&last) let (last_header, last_details) = self.chain.block_header_data(&last)
.and_then(|n| self.chain.block_details(&last).map(|d| (n, d))) .and_then(|n| self.chain.block_details(&last).map(|d| (n, d)))
.ok_or(Error::BlockNotFound(last))?; .ok_or_else(|| Error::BlockNotFound(last))?;
let parent_number = last_header.number() - 1; let parent_number = last_header.number() - 1;
let parent_hash = last_header.parent_hash(); let parent_hash = last_header.parent_hash();

View File

@ -157,7 +157,7 @@ pub fn take_snapshot<W: SnapshotWriter + Send>(
processing_threads: usize, processing_threads: usize,
) -> Result<(), Error> { ) -> Result<(), Error> {
let start_header = chain.block_header_data(&block_at) let start_header = chain.block_header_data(&block_at)
.ok_or(Error::InvalidStartingBlock(BlockId::Hash(block_at)))?; .ok_or_else(|| Error::InvalidStartingBlock(BlockId::Hash(block_at)))?;
let state_root = start_header.state_root(); let state_root = start_header.state_root();
let number = start_header.number(); let number = start_header.number();
@ -512,7 +512,7 @@ fn rebuild_accounts(
// fill out the storage trie and code while decoding. // fill out the storage trie and code while decoding.
let (acc, maybe_code) = { let (acc, maybe_code) = {
let mut acct_db = AccountDBMut::from_hash(db, hash); let mut acct_db = AccountDBMut::from_hash(db, hash);
let storage_root = known_storage_roots.get(&hash).cloned().unwrap_or(H256::zero()); let storage_root = known_storage_roots.get(&hash).cloned().unwrap_or_default();
account::from_fat_rlp(&mut acct_db, fat_rlp, storage_root)? account::from_fat_rlp(&mut acct_db, fat_rlp, storage_root)?
}; };

View File

@ -515,7 +515,7 @@ fn load_from(spec_params: SpecParams, s: ethjson::spec::Spec) -> Result<Spec, Er
chts: s.hardcoded_sync chts: s.hardcoded_sync
.as_ref() .as_ref()
.map(|s| s.chts.iter().map(|c| c.clone().into()).collect()) .map(|s| s.chts.iter().map(|c| c.clone().into()).collect())
.unwrap_or(Vec::new()), .unwrap_or_default()
}) })
} else { } else {
None None

View File

@ -82,8 +82,8 @@ pub enum ProvedExecution {
BadProof, BadProof,
/// The transaction failed, but not due to a bad proof. /// The transaction failed, but not due to a bad proof.
Failed(ExecutionError), Failed(ExecutionError),
/// The transaction successfully completd with the given proof. /// The transaction successfully completed with the given proof.
Complete(Executed), Complete(Box<Executed>),
} }
#[derive(Eq, PartialEq, Clone, Copy, Debug)] #[derive(Eq, PartialEq, Clone, Copy, Debug)]
@ -218,7 +218,7 @@ pub fn check_proof(
let options = TransactOptions::with_no_tracing().save_output_from_contract(); let options = TransactOptions::with_no_tracing().save_output_from_contract();
match state.execute(env_info, machine, transaction, options, true) { match state.execute(env_info, machine, transaction, options, true) {
Ok(executed) => ProvedExecution::Complete(executed), Ok(executed) => ProvedExecution::Complete(Box::new(executed)),
Err(ExecutionError::Internal(_)) => ProvedExecution::BadProof, Err(ExecutionError::Internal(_)) => ProvedExecution::BadProof,
Err(e) => ProvedExecution::Failed(e), Err(e) => ProvedExecution::Failed(e),
} }
@ -1254,7 +1254,7 @@ impl<B: Backend> State<B> {
let trie = TrieDB::new(db, &self.root)?; let trie = TrieDB::new(db, &self.root)?;
let maybe_account: Option<BasicAccount> = { let maybe_account: Option<BasicAccount> = {
let panicky_decoder = |bytes: &[u8]| { let panicky_decoder = |bytes: &[u8]| {
::rlp::decode(bytes).expect(&format!("prove_account, could not query trie for account key={}", &account_key)) ::rlp::decode(bytes).unwrap_or_else(|_| panic!("prove_account, could not query trie for account key={}", &account_key))
}; };
let query = (&mut recorder, panicky_decoder); let query = (&mut recorder, panicky_decoder);
trie.get_with(&account_key, query)? trie.get_with(&account_key, query)?

View File

@ -274,7 +274,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error>
return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: *expected.gas_used(), found: *got.gas_used() }))) return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: *expected.gas_used(), found: *got.gas_used() })))
} }
if expected.log_bloom() != got.log_bloom() { if expected.log_bloom() != got.log_bloom() {
return Err(From::from(BlockError::InvalidLogBloom(Mismatch { expected: *expected.log_bloom(), found: *got.log_bloom() }))) return Err(From::from(BlockError::InvalidLogBloom(Box::new(Mismatch { expected: *expected.log_bloom(), found: *got.log_bloom() }))))
} }
if expected.receipts_root() != got.receipts_root() { if expected.receipts_root() != got.receipts_root() {
return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: *expected.receipts_root(), found: *got.receipts_root() }))) return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: *expected.receipts_root(), found: *got.receipts_root() })))

View File

@ -17,7 +17,7 @@
//! Unique identifiers. //! Unique identifiers.
use ethereum_types::H256; use ethereum_types::H256;
use {BlockNumber}; use BlockNumber;
/// Uniquely identifies block. /// Uniquely identifies block.
#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)] #[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)]