Initial (non-functional) code.

- Kill Externalities Error type requirement.
This commit is contained in:
Gav
2018-01-23 17:27:43 +01:00
parent 68bdf72de7
commit 8ca5c09961
10 changed files with 72 additions and 30 deletions
+2
View File
@@ -726,10 +726,12 @@ dependencies = [
"assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"native-runtime 0.1.0",
"parity-wasm 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-primitives 0.1.0",
"polkadot-serializer 0.1.0",
"polkadot-state-machine 0.1.0",
"runtime-support 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+2
View File
@@ -13,6 +13,8 @@ serde_derive = "1.0"
parity-wasm = "0.15.0"
byteorder = "1.1"
rustc-hex = "1.0.0"
native-runtime = { path = "../native-runtime", version = "0.1" }
runtime-support = { path = "../native-runtime/support", version = "0.1" }
[dev-dependencies]
assert_matches = "1.1"
+2 -3
View File
@@ -17,7 +17,6 @@
//! Rust executor possible errors.
use serializer;
use state_machine;
error_chain! {
foreign_links {
@@ -38,9 +37,9 @@ error_chain! {
}
/// Externalities have failed.
Externalities(e: Box<state_machine::Error>) {
Externalities {
description("externalities failure"),
display("Externalities error: {}", e),
display("Externalities error"),
}
/// Invalid index.
+5
View File
@@ -34,6 +34,8 @@ extern crate serde;
extern crate parity_wasm;
extern crate byteorder;
extern crate rustc_hex;
extern crate native_runtime;
extern crate runtime_support;
#[macro_use]
extern crate error_chain;
@@ -44,10 +46,13 @@ extern crate assert_matches;
#[macro_use]
mod wasm_utils;
mod wasm_executor;
mod native_executor;
pub mod error;
/// Creates new RustExecutor for contracts.
pub fn executor() -> wasm_executor::WasmExecutor {
// TODO: check what the code to execute is and use NativeExecutor if the wasm is compiled with
// matches.
wasm_executor::WasmExecutor::default()
}
+34
View File
@@ -0,0 +1,34 @@
use primitives::contract::CallData;
use state_machine::{Externalities, CodeExecutor};
use error::{Error, ErrorKind, Result};
use native_runtime as runtime;
use runtime_support;
struct NativeExecutor;
impl CodeExecutor for NativeExecutor {
type Error = Error;
fn call<E: Externalities>(
&self,
ext: &mut E,
code: &[u8],
method: &str,
data: &CallData,
) -> Result<Vec<u8>> {
// WARNING!!! This assumes that the runtime was built *before* the main project. Until we
// get a proper build script, this must be strictly adhered to or things will go wrong.
let native_equivalent = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm");
if code == &native_equivalent[..] {
runtime_support::with_externalities(ext, || match method {
// TODO: Panic handler that comes back with error.
"execute_block" => Ok(runtime::execute_block(data.0)),
"execute_transaction" => Ok(runtime::execute_transaction(data.0)),
_ => Err(ErrorKind::MethodNotFound(method.to_owned()).into()),
})
} else {
// call into wasm.
unimplemented!()
}
}
}
+2 -3
View File
@@ -241,15 +241,14 @@ mod tests {
use super::*;
use rustc_hex::FromHex;
use state_machine::ExternalitiesError;
#[derive(Debug, Default)]
struct TestExternalities {
storage: HashMap<Vec<u8>, Vec<u8>>,
}
impl Externalities for TestExternalities {
type Error = Error;
fn storage(&self, key: &[u8]) -> Result<&[u8]> {
fn storage(&self, key: &[u8]) -> ::std::result::Result<&[u8], ExternalitiesError> {
Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice))
}
+4 -6
View File
@@ -31,7 +31,7 @@ pub use std::boxed::Box;
pub use std::slice;
pub use std::mem::{size_of, transmute, swap, uninitialized};
pub use polkadot_state_machine::Externalities;
pub use polkadot_state_machine::{Externalities, ExternalitiesError};
// TODO: use the real error, not NoError.
@@ -42,7 +42,7 @@ impl fmt::Display for NoError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") }
}
environmental!(ext : Externalities<Error=NoError> + 'static);
environmental!(ext : Externalities + 'static);
/// Get `key` from storage and return a `Vec`, empty if there's a problem.
pub fn storage(key: &[u8]) -> Vec<u8> {
@@ -93,7 +93,7 @@ pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool {
/// Execute the given closure with global function available whose functionality routes into the
/// externalities `ext`. Forwards the value that the closure returns.
pub fn with_externalities<R, F: FnOnce() -> R>(ext: &mut (Externalities<Error=NoError> + 'static), f: F) -> R {
pub fn with_externalities<R, F: FnOnce() -> R>(ext: &mut (Externalities + 'static), f: F) -> R {
ext::using(ext, f)
}
@@ -112,9 +112,7 @@ mod tests {
storage: HashMap<Vec<u8>, Vec<u8>>,
}
impl Externalities for TestExternalities {
type Error = NoError;
fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> {
fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> {
Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice))
}
+3 -5
View File
@@ -19,7 +19,7 @@
use std::{error, fmt};
use backend::Backend;
use {Externalities, OverlayedChanges};
use {Externalities, ExternalitiesError, OverlayedChanges};
/// Errors that can occur when interacting with the externalities.
#[derive(Debug, Copy, Clone)]
@@ -61,12 +61,10 @@ pub struct Ext<'a, B: 'a> {
impl<'a, B: 'a> Externalities for Ext<'a, B>
where B: Backend
{
type Error = B::Error;
fn storage(&self, key: &[u8]) -> Result<&[u8], Self::Error> {
fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> {
match self.overlay.storage(key) {
Some(x) => Ok(x),
None => self.backend.storage(key)
None => self.backend.storage(key).map_err(|_| ExternalitiesError),
}
}
+16 -9
View File
@@ -113,6 +113,18 @@ impl OverlayedChanges {
pub trait Error: 'static + fmt::Debug + fmt::Display + Send {}
impl<E> Error for E where E: 'static + fmt::Debug + fmt::Display + Send {}
/// Externalities Error.
///
/// Externalities are not really allowed to have errors, since it's assumed that dependent code
/// would not be executed unless externalities were available. This is included for completeness,
/// and as a transition away from the pre-existing framework.
#[derive(Debug, Eq, PartialEq)]
pub struct ExternalitiesError;
impl fmt::Display for ExternalitiesError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") }
}
fn to_keyed_vec(value: u32, mut prepend: Vec<u8>) -> Vec<u8> {
prepend.extend((0..::std::mem::size_of::<u32>()).into_iter().map(|i| (value >> (i * 8)) as u8));
prepend
@@ -120,11 +132,8 @@ fn to_keyed_vec(value: u32, mut prepend: Vec<u8>) -> Vec<u8> {
/// Externalities: pinned to specific active address.
pub trait Externalities {
/// Externalities error type.
type Error: Error;
/// Read storage of current contract being called.
fn storage(&self, key: &[u8]) -> Result<&[u8], Self::Error>;
fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError>;
/// Set storage of current contract being called (effective immediately).
fn set_storage(&mut self, key: Vec<u8>, value: Vec<u8>);
@@ -133,7 +142,7 @@ pub trait Externalities {
fn chain_id(&self) -> u64;
/// Get the current set of authorities from storage.
fn authorities(&self) -> Result<Vec<&[u8]>, Self::Error> {
fn authorities(&self) -> Result<Vec<&[u8]>, ExternalitiesError> {
(0..self.storage(b"con:aut:len")?.into_iter()
.rev()
.fold(0, |acc, &i| (acc << 8) + (i as u32)))
@@ -202,7 +211,7 @@ pub fn execute<B: backend::Backend, Exec: CodeExecutor>(
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use super::{OverlayedChanges, Externalities};
use super::{OverlayedChanges, Externalities, ExternalitiesError};
#[test]
fn overlayed_storage_works() {
@@ -234,9 +243,7 @@ mod tests {
storage: HashMap<Vec<u8>, Vec<u8>>,
}
impl Externalities for TestExternalities {
type Error = u8;
fn storage(&self, key: &[u8]) -> Result<&[u8], Self::Error> {
fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> {
Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice))
}
@@ -16,7 +16,7 @@
//! Testing helpers.
use runtime_support::{NoError, Externalities};
use runtime_support::{Externalities, ExternalitiesError};
use std::collections::HashMap;
use primitives::AccountID;
use statichex::StaticHexInto;
@@ -29,9 +29,7 @@ pub struct TestExternalities {
}
impl Externalities for TestExternalities {
type Error = NoError;
fn storage(&self, key: &[u8]) -> Result<&[u8], NoError> {
fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> {
Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice))
}