WIP on chain heap (#639)

* move heap size on chain

* fix the interface change

* decode heap size

* fix code comments

* fix comment

* update Cargo.lock

* rename to heappages

* add one heap pages variable in runtime
This commit is contained in:
Guanqun Lu
2018-09-01 14:41:46 +08:00
committed by Gav Wood
parent 98a2121a3c
commit beee3d4092
21 changed files with 89 additions and 95 deletions
+1
View File
@@ -3002,6 +3002,7 @@ dependencies = [
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"substrate-codec 0.1.0",
"substrate-primitives 0.1.0",
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
]
+1 -1
View File
@@ -155,7 +155,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
init_logger(log_pattern);
// Create client
let executor = NativeExecutor::with_heap_pages(8);
let executor = NativeExecutor::new();
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
let genesis_config = GenesisConfig {
+20 -20
View File
@@ -98,7 +98,7 @@ mod tests {
}
fn executor() -> ::substrate_executor::NativeExecutor<Executor> {
::substrate_executor::NativeExecutor::with_heap_pages(8)
::substrate_executor::NativeExecutor::new()
}
#[test]
@@ -114,9 +114,9 @@ mod tests {
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = executor().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
assert!(r.is_ok());
let v = executor().call(&mut t, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
let v = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
let r = ApplyResult::decode(&mut &v[..]).unwrap();
assert_eq!(r, Err(ApplyError::CantPay));
}
@@ -134,9 +134,9 @@ mod tests {
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = executor().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
assert!(r.is_ok());
let v = executor().call(&mut t, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
let v = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap();
let r = ApplyResult::decode(&mut &v[..]).unwrap();
assert_eq!(r, Err(ApplyError::CantPay));
}
@@ -154,9 +154,9 @@ mod tests {
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = executor().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
assert!(r.is_ok());
let r = executor().call(&mut t, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
let r = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
assert!(r.is_ok());
runtime_io::with_externalities(&mut t, || {
@@ -178,9 +178,9 @@ mod tests {
twox_128(&<system::BlockHash<Concrete>>::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = executor().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0;
assert!(r.is_ok());
let r = executor().call(&mut t, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
let r = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0;
assert!(r.is_ok());
runtime_io::with_externalities(&mut t, || {
@@ -312,7 +312,7 @@ mod tests {
fn full_native_block_import_works() {
let mut t = new_test_ext();
executor().call(&mut t, COMPACT_CODE, "execute_block", &block1().0, true).0.unwrap();
executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1().0, true).0.unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(Balances::total_balance(&alice()), 41);
@@ -329,7 +329,7 @@ mod tests {
]);
});
executor().call(&mut t, COMPACT_CODE, "execute_block", &block2().0, true).0.unwrap();
executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0, true).0.unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(Balances::total_balance(&alice()), 30);
@@ -359,14 +359,14 @@ mod tests {
fn full_wasm_block_import_works() {
let mut t = new_test_ext();
WasmExecutor::new(8).call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1().0).unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(Balances::total_balance(&alice()), 41);
assert_eq!(Balances::total_balance(&bob()), 69);
});
WasmExecutor::new(8).call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0).unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(Balances::total_balance(&alice()), 30);
@@ -378,7 +378,7 @@ mod tests {
fn wasm_big_block_import_fails() {
let mut t = new_test_ext();
let r = WasmExecutor::new(8).call(&mut t, COMPACT_CODE, "execute_block", &block1big().0);
let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0);
assert!(!r.is_ok());
}
@@ -386,7 +386,7 @@ mod tests {
fn native_big_block_import_succeeds() {
let mut t = new_test_ext();
let r = Executor::with_heap_pages(8).call(&mut t, COMPACT_CODE, "execute_block", &block1big().0, true).0;
let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, true).0;
assert!(r.is_ok());
}
@@ -394,7 +394,7 @@ mod tests {
fn native_big_block_import_fails_on_fallback() {
let mut t = new_test_ext();
let r = Executor::with_heap_pages(8).call(&mut t, COMPACT_CODE, "execute_block", &block1big().0, false).0;
let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, false).0;
assert!(!r.is_ok());
}
@@ -412,9 +412,9 @@ mod tests {
];
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm");
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
assert!(r.is_ok());
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
let r = ApplyResult::decode(&mut &r[..]).unwrap();
assert_eq!(r, Err(ApplyError::CantPay));
}
@@ -433,9 +433,9 @@ mod tests {
];
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm");
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64)));
assert!(r.is_ok());
let r = WasmExecutor::new(8).call(&mut t, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap();
let r = ApplyResult::decode(&mut &r[..]).unwrap();
assert_eq!(r, Ok(ApplyOutcome::Success));
+1
View File
@@ -903,6 +903,7 @@ dependencies = [
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"substrate-codec 0.1.0",
"substrate-primitives 0.1.0",
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
]
-4
View File
@@ -125,10 +125,6 @@ args:
long: execution
value_name: STRATEGY
help: The means of execution used when calling into the runtime. Can be either wasm, native or both.
- max-heap-pages:
long: max-heap-pages
value_name: COUNT
help: The maximum number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing.
subcommands:
- build-spec:
about: Build a spec.json file, outputing to stdout
-8
View File
@@ -266,10 +266,6 @@ where
service::Roles::FULL
};
if let Some(v) = matches.value_of("max-heap-pages") {
config.max_heap_pages = v.parse().map_err(|_| "Invalid --max-heap-pages argument")?;
}
if let Some(s) = matches.value_of("execution") {
config.execution_strategy = match s {
"both" => service::ExecutionStrategy::Both,
@@ -398,10 +394,6 @@ fn import_blocks<F, E>(matches: &clap::ArgMatches, spec: ChainSpec<FactoryGenesi
let mut config = service::Configuration::default_with_spec(spec);
config.database_path = db_path(&base_path, config.chain_spec.id()).to_string_lossy().into();
if let Some(v) = matches.value_of("max-heap-pages") {
config.max_heap_pages = v.parse().map_err(|_| "Invalid --max-heap-pages argument")?;
}
if let Some(s) = matches.value_of("execution") {
config.execution_strategy = match s {
"both" => service::ExecutionStrategy::Both,
@@ -26,6 +26,7 @@ use patricia_trie::NodeCodec;
use primitives::{KeccakHasher, RlpCodec};
use hashdb::Hasher;
use rlp::Encodable;
use codec::Decode;
use backend;
use error;
@@ -145,8 +146,9 @@ where
let mut externalities = Ext::new(&mut overlay, &state);
let code = externalities.storage(b":code").ok_or(error::ErrorKind::VersionInvalid)?
.to_vec();
let heap_pages = externalities.storage(b":heappages").and_then(|v| u64::decode(&mut &v[..])).unwrap_or(8) as usize;
self.executor.runtime_version(&mut externalities, &code)
self.executor.runtime_version(&mut externalities, heap_pages, &code)
.ok_or(error::ErrorKind::VersionInvalid.into())
}
+2 -2
View File
@@ -56,7 +56,7 @@ mod tests {
native_executor_instance!(Executor, test_client::runtime::api::dispatch, test_client::runtime::VERSION, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
fn executor() -> ::executor::NativeExecutor<Executor> {
NativeExecutionDispatch::with_heap_pages(8)
NativeExecutionDispatch::new()
}
fn construct_block(backend: &InMemory<KeccakHasher, RlpCodec>, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transfer>) -> (Vec<u8>, Hash) {
@@ -194,7 +194,7 @@ mod tests {
let _ = execute(
&backend,
&mut overlay,
&Executor::with_heap_pages(8),
&Executor::new(),
"execute_block",
&b1data,
ExecutionStrategy::NativeWhenPossible,
@@ -270,7 +270,7 @@ pub mod tests {
let remote_read_proof = remote_client.read_proof(&remote_block_id, b":auth:len").unwrap();
// check remote read proof locally
let local_executor = test_client::LocalExecutor::with_heap_pages(8);
let local_executor = test_client::LocalExecutor::new();
let local_checker = new_fetch_checker::<_, KeccakHasher, RlpCodec>(local_executor);
let request = RemoteReadRequest {
block: remote_block_hash,
@@ -156,7 +156,7 @@ mod tests {
let remote_execution_proof = remote_client.execution_proof(&remote_block_id, "authorities", &[]).unwrap().1;
// check remote execution proof locally
let local_executor = test_client::LocalExecutor::with_heap_pages(8);
let local_executor = test_client::LocalExecutor::new();
check_execution_proof::<_, _, _, RlpCodec>(&local_executor, &RemoteCallRequest {
block: test_client::runtime::Hash::default(),
header: test_client::runtime::Header {
+1
View File
@@ -87,6 +87,7 @@ pub trait RuntimeInfo {
fn runtime_version<E: Externalities<KeccakHasher>> (
&self,
ext: &mut E,
heap_pages: usize,
code: &[u8]
) -> Option<RuntimeVersion>;
}
@@ -55,12 +55,13 @@ fn fetch_cached_runtime_version<'a, E: Externalities<KeccakHasher>>(
wasm_executor: &WasmExecutor,
cache: &'a mut MutexGuard<CacheType>,
ext: &mut E,
heap_pages: usize,
code: &[u8]
) -> Result<(&'a WasmModule, &'a Option<RuntimeVersion>)> {
let maybe_runtime_preproc = cache.entry(gen_cache_key(code))
.or_insert_with(|| match WasmModule::from_buffer(code) {
Ok(module) => {
let version = wasm_executor.call_in_wasm_module(ext, &module, "version", &[])
let version = wasm_executor.call_in_wasm_module(ext, heap_pages, &module, "version", &[])
.ok()
.and_then(|v| RuntimeVersion::decode(&mut v.as_slice()));
RuntimePreproc::ValidCode(module, version)
@@ -108,9 +109,9 @@ pub trait NativeExecutionDispatch: Send + Sync {
/// Get native runtime version.
const VERSION: RuntimeVersion;
/// Construct corresponding `NativeExecutor` with given `heap_pages`.
fn with_heap_pages(max_heap_pages: usize) -> NativeExecutor<Self> where Self: Sized {
NativeExecutor::with_heap_pages(max_heap_pages)
/// Construct corresponding `NativeExecutor`
fn new() -> NativeExecutor<Self> where Self: Sized {
NativeExecutor::new()
}
}
@@ -125,11 +126,11 @@ pub struct NativeExecutor<D: NativeExecutionDispatch> {
}
impl<D: NativeExecutionDispatch> NativeExecutor<D> {
/// Create new instance with specific number of pages for wasm fallback's heap.
pub fn with_heap_pages(max_heap_pages: usize) -> Self {
/// Create new instance.
pub fn new() -> Self {
NativeExecutor {
_dummy: Default::default(),
fallback: WasmExecutor::new(max_heap_pages),
fallback: WasmExecutor::new(),
}
}
}
@@ -149,9 +150,10 @@ impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
fn runtime_version<E: Externalities<KeccakHasher>>(
&self,
ext: &mut E,
heap_pages: usize,
code: &[u8],
) -> Option<RuntimeVersion> {
fetch_cached_runtime_version(&self.fallback, &mut RUNTIMES_CACHE.lock(), ext, code).ok()?.1.clone()
fetch_cached_runtime_version(&self.fallback, &mut RUNTIMES_CACHE.lock(), ext, heap_pages, code).ok()?.1.clone()
}
}
@@ -161,23 +163,24 @@ impl<D: NativeExecutionDispatch> CodeExecutor<KeccakHasher> for NativeExecutor<D
fn call<E: Externalities<KeccakHasher>>(
&self,
ext: &mut E,
heap_pages: usize,
code: &[u8],
method: &str,
data: &[u8],
use_native: bool,
) -> (Result<Vec<u8>>, bool) {
let mut c = RUNTIMES_CACHE.lock();
let (module, onchain_version) = match fetch_cached_runtime_version(&self.fallback, &mut c, ext, code) {
let (module, onchain_version) = match fetch_cached_runtime_version(&self.fallback, &mut c, ext, heap_pages, code) {
Ok((module, onchain_version)) => (module, onchain_version),
Err(_) => return (Err(ErrorKind::InvalidCode(code.into()).into()), false),
};
match (use_native, onchain_version.as_ref().map_or(false, |v| v.can_call_with(&D::VERSION))) {
(_, false) => {
trace!(target: "executor", "Request for native execution failed (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
(self.fallback.call_in_wasm_module(ext, module, method, data), false)
(self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false)
}
(false, _) => {
(self.fallback.call_in_wasm_module(ext, module, method, data), false)
(self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false)
}
_ => {
trace!(target: "executor", "Request for native execution succeeded (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
@@ -213,8 +216,8 @@ macro_rules! native_executor_instance {
.ok_or_else(|| $crate::error::ErrorKind::MethodNotFound(method.to_owned()).into())
}
fn with_heap_pages(max_heap_pages: usize) -> $crate::NativeExecutor<$name> {
$crate::NativeExecutor::with_heap_pages(max_heap_pages)
fn new() -> $crate::NativeExecutor<$name> {
$crate::NativeExecutor::new()
}
}
}
+5 -5
View File
@@ -554,7 +554,7 @@ mod tests {
"#).unwrap();
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox", &code).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(),
vec![1],
);
}
@@ -575,7 +575,7 @@ mod tests {
"#).unwrap();
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox", &code).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(),
vec![0],
);
}
@@ -613,7 +613,7 @@ mod tests {
"#).unwrap();
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox", &code).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox", &code).unwrap(),
vec![1],
);
}
@@ -647,7 +647,7 @@ mod tests {
"#).unwrap();
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox_args", &code).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_args", &code).unwrap(),
vec![1],
);
}
@@ -669,7 +669,7 @@ mod tests {
"#).unwrap();
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_sandbox_return_val", &code).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sandbox_return_val", &code).unwrap(),
vec![1],
);
}
@@ -496,47 +496,36 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
/// Wasm rust executor for contracts.
///
/// Executes the provided code in a sandboxed wasm runtime.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct WasmExecutor {
/// The max number of pages to allocate for the heap.
pub max_heap_pages: usize,
}
impl Clone for WasmExecutor {
fn clone(&self) -> Self {
WasmExecutor {
max_heap_pages: self.max_heap_pages,
}
}
}
impl WasmExecutor {
/// Create a new instance.
pub fn new(max_heap_pages: usize) -> Self {
WasmExecutor {
max_heap_pages,
}
pub fn new() -> Self {
WasmExecutor{}
}
/// Call a given method in the given code.
/// This should be used for tests only.
pub fn call<E: Externalities<KeccakHasher>>(
&self,
ext: &mut E,
heap_pages: usize,
code: &[u8],
method: &str,
data: &[u8],
) -> Result<Vec<u8>> {
let module = ::wasmi::Module::from_buffer(code).expect("all modules compiled with rustc are valid wasm code; qed");
self.call_in_wasm_module(ext, &module, method, data)
self.call_in_wasm_module(ext, heap_pages, &module, method, data)
}
/// Call a given method in the given wasm-module runtime.
pub fn call_in_wasm_module<E: Externalities<KeccakHasher>>(
&self,
ext: &mut E,
heap_pages: usize,
module: &Module,
method: &str,
data: &[u8],
@@ -564,7 +553,7 @@ impl WasmExecutor {
.export_by_name("__indirect_function_table")
.and_then(|e| e.as_table().cloned());
let mut fec = FunctionExecutor::new(memory.clone(), self.max_heap_pages, table, ext)?;
let mut fec = FunctionExecutor::new(memory.clone(), heap_pages, table, ext)?;
// finish instantiation by running 'start' function (if any).
let instance = intermediate_instance.run_start(&mut fec)?;
@@ -585,7 +574,7 @@ impl WasmExecutor {
let returned = match result {
Ok(x) => x,
Err(e) => {
trace!(target: "wasm-executor", "Failed to execute code with {} pages", self.max_heap_pages);
trace!(target: "wasm-executor", "Failed to execute code with {} pages", heap_pages);
return Err(e.into())
},
};
@@ -620,7 +609,7 @@ mod tests {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_empty_return", &[]).unwrap();
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap();
assert_eq!(output, vec![0u8; 0]);
}
@@ -629,10 +618,10 @@ mod tests {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_panic", &[]);
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_panic", &[]);
assert!(output.is_err());
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_conditional_panic", &[2]);
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[2]);
assert!(output.is_err());
}
@@ -642,7 +631,7 @@ mod tests {
ext.set_storage(b"foo".to_vec(), b"bar".to_vec());
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_data_in", b"Hello world").unwrap();
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_data_in", b"Hello world").unwrap();
assert_eq!(output, b"all ok!".to_vec());
@@ -665,7 +654,7 @@ mod tests {
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
// This will clear all entries which prefix is "ab".
let output = WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_clear_prefix", b"ab").unwrap();
let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_clear_prefix", b"ab").unwrap();
assert_eq!(output, b"all ok!".to_vec());
@@ -682,11 +671,11 @@ mod tests {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_blake2_256", &[]).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", &[]).unwrap(),
blake2_256(&b""[..]).encode()
);
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(),
blake2_256(&b"Hello world!"[..]).encode()
);
}
@@ -696,11 +685,11 @@ mod tests {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_256", &[]).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", &[]).unwrap(),
hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a")
);
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_256", b"Hello world!").unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_256", b"Hello world!").unwrap(),
hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74")
);
}
@@ -710,11 +699,11 @@ mod tests {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_128", &[]).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", &[]).unwrap(),
hex!("99e9d85137db46ef4bbea33613baafd5")
);
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_twox_128", b"Hello world!").unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_twox_128", b"Hello world!").unwrap(),
hex!("b27dfd7f223f177f2a13647b533599af")
);
}
@@ -730,7 +719,7 @@ mod tests {
calldata.extend_from_slice(sig.as_ref());
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
vec![1]
);
@@ -740,7 +729,7 @@ mod tests {
calldata.extend_from_slice(other_sig.as_ref());
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_ed25519_verify", &calldata).unwrap(),
vec![0]
);
}
@@ -750,7 +739,7 @@ mod tests {
let mut ext = TestExternalities::default();
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor::new(8).call(&mut ext, &test_code[..], "test_enumerated_trie_root", &[]).unwrap(),
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_enumerated_trie_root", &[]).unwrap(),
ordered_trie_root(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]).0.encode()
);
}
@@ -59,8 +59,6 @@ pub struct Configuration<C, G: Serialize + DeserializeOwned + BuildStorage> {
pub name: String,
/// Execution strategy.
pub execution_strategy: ExecutionStrategy,
/// Maximum number of heap pages to allocate for Wasm execution.
pub max_heap_pages: usize,
/// RPC over HTTP binding address. `None` if disabled.
pub rpc_http: Option<SocketAddr>,
/// RPC over Websockets binding address. `None` if disabled.
@@ -88,7 +86,6 @@ impl<C: Default, G: Serialize + DeserializeOwned + BuildStorage> Configuration<C
telemetry: Default::default(),
pruning: PruningMode::default(),
execution_strategy: ExecutionStrategy::Both,
max_heap_pages: 1024,
rpc_http: None,
rpc_ws: None,
telemetry_url: None,
+2 -2
View File
@@ -100,7 +100,7 @@ pub struct Service<Components: components::Components> {
pub fn new_client<Factory: components::ServiceFactory>(config: FactoryFullConfiguration<Factory>)
-> Result<Arc<ComponentClient<components::FullComponents<Factory>>>, error::Error>
{
let executor = NativeExecutor::with_heap_pages(config.max_heap_pages);
let executor = NativeExecutor::new();
let (client, _) = components::FullComponents::<Factory>::build_client(
&config,
executor,
@@ -122,7 +122,7 @@ impl<Components> Service<Components>
let (signal, exit) = ::exit_future::signal();
// Create client
let executor = NativeExecutor::with_heap_pages(config.max_heap_pages);
let executor = NativeExecutor::new();
let mut keystore = Keystore::open(config.keystore_path.as_str().into())?;
for seed in &config.keys {
@@ -12,6 +12,7 @@ parking_lot = "0.4"
heapsize = "0.4"
substrate-primitives = { path = "../primitives", version = "0.1.0" }
substrate-codec = { path = "../codec", default_features = false }
hashdb = { git = "https://github.com/paritytech/parity-common" }
memorydb = { git = "https://github.com/paritytech/parity-common" }
@@ -34,6 +34,7 @@ extern crate rlp;
extern crate heapsize;
#[cfg(test)]
extern crate substrate_primitives as primitives;
extern crate substrate_codec as codec;
use std::collections::HashMap;
use std::fmt;
@@ -41,6 +42,7 @@ use hashdb::Hasher;
use patricia_trie::NodeCodec;
use rlp::Encodable;
use heapsize::HeapSizeOf;
use codec::Decode;
pub mod backend;
mod ext;
@@ -206,6 +208,7 @@ pub trait CodeExecutor<H: Hasher>: Sized + Send + Sync {
fn call<E: Externalities<H>>(
&self,
ext: &mut E,
heap_pages: usize,
code: &[u8],
method: &str,
data: &[u8],
@@ -325,6 +328,9 @@ where
.ok_or_else(|| Box::new(ExecutionError::CodeEntryDoesNotExist) as Box<Error>)?
.to_vec();
let heap_pages = ext::Ext::new(overlay, backend).storage(b":heappages")
.and_then(|v| u64::decode(&mut &v[..])).unwrap_or(8) as usize;
let result = {
let mut orig_prospective = overlay.prospective.clone();
@@ -334,6 +340,7 @@ where
(
exec.call(
&mut externalities,
heap_pages,
&code,
method,
call_data,
@@ -358,6 +365,7 @@ where
(
exec.call(
&mut externalities,
heap_pages,
&code,
method,
call_data,
@@ -488,6 +496,7 @@ mod tests {
fn call<E: Externalities<H>>(
&self,
ext: &mut E,
_heap_pages: usize,
_code: &[u8],
_method: &str,
_data: &[u8],
@@ -39,7 +39,7 @@ pub trait TestClient {
impl TestClient for Client<Backend, Executor, runtime::Block> {
fn new_for_tests() -> Self {
client::new_in_mem(NativeExecutor::with_heap_pages(8), genesis_storage()).unwrap()
client::new_in_mem(NativeExecutor::new(), genesis_storage()).unwrap()
}
fn justify_and_import(&self, origin: client::BlockOrigin, block: runtime::Block) -> client::error::Result<()> {
@@ -43,6 +43,7 @@ impl GenesisConfig {
.map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec()))
.chain(vec![
(b":code"[..].into(), wasm_runtime),
(b":heappages"[..].into(), vec![].and(&(16 as u64))),
(b":auth:len"[..].into(), vec![].and(&(self.authorities.len() as u32))),
].into_iter())
.chain(self.authorities.iter()
+1
View File
@@ -661,6 +661,7 @@ dependencies = [
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.2.1 (git+https://github.com/paritytech/parity-common)",
"rlp 0.2.1 (git+https://github.com/paritytech/parity-common)",
"substrate-codec 0.1.0",
"substrate-primitives 0.1.0",
"triehash 0.2.0 (git+https://github.com/paritytech/parity-common)",
]