Reorganising the repository - external renames and moves (#4074)

* Adding first rough ouline of the repository structure

* Remove old CI stuff

* add title

* formatting fixes

* move node-exits job's script to scripts dir

* Move docs into subdir

* move to bin

* move maintainence scripts, configs and helpers into its own dir

* add .local to ignore

* move core->client

* start up 'test' area

* move test client

* move test runtime

* make test move compile

* Add dependencies rule enforcement.

* Fix indexing.

* Update docs to reflect latest changes

* Moving /srml->/paint

* update docs

* move client/sr-* -> primitives/

* clean old readme

* remove old broken code in rhd

* update lock

* Step 1.

* starting to untangle client

* Fix after merge.

* start splitting out client interfaces

* move children and blockchain interfaces

* Move trie and state-machine to primitives.

* Fix WASM builds.

* fixing broken imports

* more interface moves

* move backend and light to interfaces

* move CallExecutor

* move cli off client

* moving around more interfaces

* re-add consensus crates into the mix

* fix subkey path

* relieve client from executor

* starting to pull out client from grandpa

* move is_decendent_of out of client

* grandpa still depends on client directly

* lemme tests pass

* rename srml->paint

* Make it compile.

* rename interfaces->client-api

* Move keyring to primitives.

* fixup libp2p dep

* fix broken use

* allow dependency enforcement to fail

* move fork-tree

* Moving wasm-builder

* make env

* move build-script-utils

* fixup broken crate depdencies and names

* fix imports for authority discovery

* fix typo

* update cargo.lock

* fixing imports

* Fix paths and add missing crates

* re-add missing crates
This commit is contained in:
Benjamin Kampmann
2019-11-14 21:51:17 +01:00
committed by Bastian Köcher
parent becc3b0a4f
commit 60e5011c72
809 changed files with 7801 additions and 6464 deletions
@@ -0,0 +1,285 @@
// Copyright 2017-2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use crate::{
RuntimeInfo, error::{Error, Result},
wasm_runtime::{RuntimesCache, WasmExecutionMethod, WasmRuntime},
};
use runtime_version::{NativeVersion, RuntimeVersion};
use codec::{Decode, Encode};
use primitives::{NativeOrEncoded, traits::{CodeExecutor, Externalities}};
use log::{trace, warn};
use std::{result, cell::RefCell, panic::{UnwindSafe, AssertUnwindSafe}};
use wasm_interface::{HostFunctions, Function};
thread_local! {
static RUNTIMES_CACHE: RefCell<RuntimesCache> = RefCell::new(RuntimesCache::new());
}
/// Default num of pages for the heap
const DEFAULT_HEAP_PAGES: u64 = 1024;
pub(crate) fn safe_call<F, U>(f: F) -> Result<U>
where F: UnwindSafe + FnOnce() -> U
{
// Substrate uses custom panic hook that terminates process on panic. Disable termination for the native call.
let _guard = panic_handler::AbortGuard::force_unwind();
std::panic::catch_unwind(f).map_err(|_| Error::Runtime)
}
/// Set up the externalities and safe calling environment to execute calls to a native runtime.
///
/// If the inner closure panics, it will be caught and return an error.
pub fn with_native_environment<F, U>(ext: &mut dyn Externalities, f: F) -> Result<U>
where F: UnwindSafe + FnOnce() -> U
{
externalities::set_and_run_with_externalities(ext, move || safe_call(f))
}
/// Delegate for dispatching a CodeExecutor call.
///
/// By dispatching we mean that we execute a runtime function specified by it's name.
pub trait NativeExecutionDispatch: Send + Sync {
/// Dispatch a method in the runtime.
///
/// If the method with the specified name doesn't exist then `Err` is returned.
fn dispatch(ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result<Vec<u8>>;
/// Provide native runtime version.
fn native_version() -> NativeVersion;
}
/// A generic `CodeExecutor` implementation that uses a delegate to determine wasm code equivalence
/// and dispatch to native code when possible, falling back on `WasmExecutor` when not.
pub struct NativeExecutor<D> {
/// Dummy field to avoid the compiler complaining about us not using `D`.
_dummy: std::marker::PhantomData<D>,
/// Method used to execute fallback Wasm code.
fallback_method: WasmExecutionMethod,
/// Native runtime version info.
native_version: NativeVersion,
/// The number of 64KB pages to allocate for Wasm execution.
default_heap_pages: u64,
/// The host functions registered with this instance.
host_functions: Vec<&'static dyn Function>,
}
impl<D: NativeExecutionDispatch> NativeExecutor<D> {
/// Create new instance.
///
/// # Parameters
///
/// `fallback_method` - Method used to execute fallback Wasm code.
///
/// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution.
/// Defaults to `DEFAULT_HEAP_PAGES` if `None` is provided.
pub fn new(fallback_method: WasmExecutionMethod, default_heap_pages: Option<u64>) -> Self {
let mut host_functions = runtime_io::SubstrateHostFunctions::host_functions();
// Add the old and deprecated host functions as well, so that we support old wasm runtimes.
host_functions.extend(
crate::deprecated_host_interface::SubstrateExternals::host_functions(),
);
NativeExecutor {
_dummy: Default::default(),
fallback_method,
native_version: D::native_version(),
default_heap_pages: default_heap_pages.unwrap_or(DEFAULT_HEAP_PAGES),
host_functions,
}
}
/// Execute the given closure `f` with the latest runtime (based on the `CODE` key in `ext`).
///
/// The closure `f` is expected to return `Err(_)` when there happened a `panic!` in native code
/// while executing the runtime in Wasm. If a `panic!` occurred, the runtime is invalidated to
/// prevent any poisoned state. Native runtime execution does not need to report back
/// any `panic!`.
///
/// # Safety
///
/// `runtime` and `ext` are given as `AssertUnwindSafe` to the closure. As described above, the
/// runtime is invalidated on any `panic!` to prevent a poisoned state. `ext` is already
/// implicitly handled as unwind safe, as we store it in a global variable while executing the
/// native runtime.
fn with_runtime<E, R>(
&self,
ext: &mut E,
f: impl for<'a> FnOnce(
AssertUnwindSafe<&'a mut (dyn WasmRuntime + 'static)>,
&'a RuntimeVersion,
AssertUnwindSafe<&'a mut E>,
) -> Result<Result<R>>,
) -> Result<R> where E: Externalities {
RUNTIMES_CACHE.with(|cache| {
let mut cache = cache.borrow_mut();
let (runtime, version, code_hash) = cache.fetch_runtime(
ext,
self.fallback_method,
self.default_heap_pages,
&self.host_functions,
)?;
let runtime = AssertUnwindSafe(runtime);
let ext = AssertUnwindSafe(ext);
match f(runtime, version, ext) {
Ok(res) => res,
Err(e) => {
cache.invalidate_runtime(self.fallback_method, code_hash);
Err(e)
}
}
})
}
}
impl<D: NativeExecutionDispatch> Clone for NativeExecutor<D> {
fn clone(&self) -> Self {
NativeExecutor {
_dummy: Default::default(),
fallback_method: self.fallback_method,
native_version: D::native_version(),
default_heap_pages: self.default_heap_pages,
host_functions: self.host_functions.clone(),
}
}
}
impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
fn native_version(&self) -> &NativeVersion {
&self.native_version
}
fn runtime_version<E: Externalities>(
&self,
ext: &mut E,
) -> Option<RuntimeVersion> {
match self.with_runtime(ext, |_runtime, version, _ext| Ok(Ok(version.clone()))) {
Ok(version) => Some(version),
Err(e) => {
warn!(target: "executor", "Failed to fetch runtime: {:?}", e);
None
}
}
}
}
impl<D: NativeExecutionDispatch> CodeExecutor for NativeExecutor<D> {
type Error = Error;
fn call
<
E: Externalities,
R: Decode + Encode + PartialEq,
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
>(
&self,
ext: &mut E,
method: &str,
data: &[u8],
use_native: bool,
native_call: Option<NC>,
) -> (Result<NativeOrEncoded<R>>, bool){
let mut used_native = false;
let result = self.with_runtime(ext, |mut runtime, onchain_version, mut ext| {
match (
use_native,
onchain_version.can_call_with(&self.native_version.runtime_version),
native_call,
) {
(_, false, _) => {
trace!(
target: "executor",
"Request for native execution failed (native: {}, chain: {})",
self.native_version.runtime_version,
onchain_version,
);
safe_call(
move || runtime.call(&mut **ext, method, data).map(NativeOrEncoded::Encoded)
)
}
(false, _, _) => {
safe_call(
move || runtime.call(&mut **ext, method, data).map(NativeOrEncoded::Encoded)
)
},
(true, true, Some(call)) => {
trace!(
target: "executor",
"Request for native execution with native call succeeded (native: {}, chain: {}).",
self.native_version.runtime_version,
onchain_version,
);
used_native = true;
let res = with_native_environment(&mut **ext, move || (call)())
.and_then(|r| r
.map(NativeOrEncoded::Native)
.map_err(|s| Error::ApiError(s.to_string()))
);
Ok(res)
}
_ => {
trace!(
target: "executor",
"Request for native execution succeeded (native: {}, chain: {})",
self.native_version.runtime_version,
onchain_version
);
used_native = true;
Ok(D::dispatch(&mut **ext, method, data).map(NativeOrEncoded::Encoded))
}
}
});
(result, used_native)
}
}
/// Implements a `NativeExecutionDispatch` for provided parameters.
#[macro_export]
macro_rules! native_executor_instance {
( $pub:vis $name:ident, $dispatcher:path, $version:path $(,)?) => {
/// A unit struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime.
$pub struct $name;
$crate::native_executor_instance!(IMPL $name, $dispatcher, $version);
};
(IMPL $name:ident, $dispatcher:path, $version:path) => {
impl $crate::NativeExecutionDispatch for $name {
fn dispatch(
ext: &mut $crate::Externalities,
method: &str,
data: &[u8]
) -> $crate::error::Result<Vec<u8>> {
$crate::with_native_environment(ext, move || $dispatcher(method, data))?
.ok_or_else(|| $crate::error::Error::MethodNotFound(method.to_owned()))
}
fn native_version() -> $crate::NativeVersion {
$version()
}
}
}
}