State cache and other performance optimizations (#1345)

* State caching

* Better code caching

* Execution optimizaton

* More optimizations

* Updated wasmi

* Caching test

* Style

* Style

* Reverted some minor changes

* Style and typos

* Style and typos

* Removed panics on missing memory
This commit is contained in:
Arkadiy Paronyan
2019-01-08 15:13:13 +03:00
committed by Gav Wood
parent e0639c435b
commit b104c02eb6
26 changed files with 796 additions and 266 deletions
+6 -1
View File
@@ -188,7 +188,7 @@ where
self.authorities = Some(authorities);
}
fn update_storage(&mut self, _update: <Self::State as StateBackend<H>>::Transaction) -> ClientResult<()> {
fn update_db_storage(&mut self, _update: <Self::State as StateBackend<H>>::Transaction) -> ClientResult<()> {
// we're not storing anything locally => ignore changes
Ok(())
}
@@ -210,6 +210,11 @@ where
self.aux_ops = ops.into_iter().collect();
Ok(())
}
fn update_storage(&mut self, _update: Vec<(Vec<u8>, Option<Vec<u8>>)>) -> ClientResult<()> {
// we're not storing anything locally => ignore changes
Ok(())
}
}
impl<Block, S, F, H> StateBackend<H> for OnDemandState<Block, S, F>
@@ -31,7 +31,7 @@ use state_machine::{self, Backend as StateBackend, CodeExecutor, OverlayedChange
use hash_db::Hasher;
use blockchain::Backend as ChainBackend;
use call_executor::{CallExecutor, CallResult};
use call_executor::CallExecutor;
use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult};
use light::fetcher::{Fetcher, RemoteCallRequest};
use executor::{RuntimeVersion, NativeVersion};
@@ -74,7 +74,7 @@ where
{
type Error = ClientError;
fn call(&self, id: &BlockId<Block>, method: &str, call_data: &[u8]) -> ClientResult<CallResult> {
fn call(&self, id: &BlockId<Block>, method: &str, call_data: &[u8]) -> ClientResult<Vec<u8>> {
let block_hash = self.blockchain.expect_block_hash_from_id(id)?;
let block_header = self.blockchain.expect_header(id.clone())?;
@@ -105,12 +105,12 @@ where
return Err(ClientErrorKind::NotAvailableOnLightClient.into());
}
self.call(at, method, call_data).map(|cr| cr.return_data)
self.call(at, method, call_data)
}
fn runtime_version(&self, id: &BlockId<Block>) -> ClientResult<RuntimeVersion> {
let call_result = self.call(id, "version", &[])?;
RuntimeVersion::decode(&mut call_result.return_data.as_slice())
RuntimeVersion::decode(&mut call_result.as_slice())
.ok_or_else(|| ClientErrorKind::VersionInvalid.into())
}
@@ -189,7 +189,7 @@ pub fn check_execution_proof<Header, E, H>(
executor: &E,
request: &RemoteCallRequest<Header>,
remote_proof: Vec<Vec<u8>>
) -> ClientResult<CallResult>
) -> ClientResult<Vec<u8>>
where
Header: HeaderT,
E: CodeExecutor<H>,
@@ -226,7 +226,7 @@ pub fn check_execution_proof<Header, E, H>(
&request.call_data,
)?;
Ok(CallResult { return_data: local_result, changes })
Ok(local_result)
}
#[cfg(test)]
@@ -273,7 +273,7 @@ mod tests {
retry_count: None,
}, remote_execution_proof).unwrap();
(remote_result, local_result.return_data)
(remote_result, local_result)
}
// prepare remote client
+5 -7
View File
@@ -28,7 +28,6 @@ use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT, NumberF
use state_machine::{CodeExecutor, ChangesTrieRootsStorage, ChangesTrieAnchorBlockId,
TrieBackend, read_proof_check, key_changes_proof_check, create_proof_check_backend_storage};
use call_executor::CallResult;
use cht;
use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult};
use light::blockchain::{Blockchain, Storage as BlockchainStorage};
@@ -118,7 +117,7 @@ pub trait Fetcher<Block: BlockT>: Send + Sync {
/// Remote storage read future.
type RemoteReadResult: IntoFuture<Item=Option<Vec<u8>>, Error=ClientError>;
/// Remote call result future.
type RemoteCallResult: IntoFuture<Item=CallResult, Error=ClientError>;
type RemoteCallResult: IntoFuture<Item=Vec<u8>, Error=ClientError>;
/// Remote changes result future.
type RemoteChangesResult: IntoFuture<Item=Vec<(NumberFor<Block>, u32)>, Error=ClientError>;
@@ -156,7 +155,7 @@ pub trait FetchChecker<Block: BlockT>: Send + Sync {
&self,
request: &RemoteCallRequest<Block::Header>,
remote_proof: Vec<Vec<u8>>
) -> ClientResult<CallResult>;
) -> ClientResult<Vec<u8>>;
/// Check remote changes query proof.
fn check_changes_proof(
&self,
@@ -344,7 +343,7 @@ impl<E, Block, H, S, F> FetchChecker<Block> for LightDataChecker<E, H, Block, S,
&self,
request: &RemoteCallRequest<Block::Header>,
remote_proof: Vec<Vec<u8>>
) -> ClientResult<CallResult> {
) -> ClientResult<Vec<u8>> {
check_execution_proof::<_, _, H>(&self.executor, request, remote_proof)
}
@@ -392,7 +391,6 @@ pub mod tests {
use futures::future::{ok, err, FutureResult};
use parking_lot::Mutex;
use keyring::Keyring;
use call_executor::CallResult;
use client::tests::prepare_client_with_key_changes;
use executor::{self, NativeExecutionDispatch};
use error::Error as ClientError;
@@ -410,12 +408,12 @@ pub mod tests {
use state_machine::Backend;
use super::*;
pub type OkCallFetcher = Mutex<CallResult>;
pub type OkCallFetcher = Mutex<Vec<u8>>;
impl Fetcher<Block> for OkCallFetcher {
type RemoteHeaderResult = FutureResult<Header, ClientError>;
type RemoteReadResult = FutureResult<Option<Vec<u8>>, ClientError>;
type RemoteCallResult = FutureResult<CallResult, ClientError>;
type RemoteCallResult = FutureResult<Vec<u8>, ClientError>;
type RemoteChangesResult = FutureResult<Vec<(NumberFor<Block>, u32)>, ClientError>;
fn remote_header(&self, _request: RemoteHeaderRequest<Header>) -> Self::RemoteHeaderResult {