Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
@@ -23,8 +23,8 @@
// borthersome.
#![cfg(feature = "wasmtime")]
use crate::WasmExecutionMethod;
use super::mk_test_runtime;
use crate::WasmExecutionMethod;
use codec::Encode as _;
mod smaps;
@@ -54,17 +54,11 @@ fn memory_consumption_compiled() {
}
instance
.call_export(
"test_dirty_plenty_memory",
&(heap_base as u32, 1u32).encode(),
)
.call_export("test_dirty_plenty_memory", &(heap_base as u32, 1u32).encode())
.unwrap();
let probe_1 = probe_rss(&*instance);
instance
.call_export(
"test_dirty_plenty_memory",
&(heap_base as u32, 1024u32).encode(),
)
.call_export("test_dirty_plenty_memory", &(heap_base as u32, 1024u32).encode())
.unwrap();
let probe_2 = probe_rss(&*instance);
@@ -19,8 +19,7 @@
//! A tool for extracting information about the memory consumption of the current process from
//! the procfs.
use std::ops::Range;
use std::collections::BTreeMap;
use std::{collections::BTreeMap, ops::Range};
/// An interface to the /proc/self/smaps
///
@@ -69,7 +68,8 @@ impl Smaps {
}
fn get_map(&self, addr: usize) -> &BTreeMap<String, usize> {
&self.0
&self
.0
.iter()
.find(|(range, _)| addr >= range.start && addr < range.end)
.unwrap()
@@ -20,20 +20,22 @@
mod linux;
mod sandbox;
use std::sync::Arc;
use codec::{Encode, Decode};
use codec::{Decode, Encode};
use hex_literal::hex;
use sp_core::{
blake2_128, blake2_256, ed25519, sr25519, map, Pair,
offchain::{OffchainWorkerExt, OffchainDbExt, testing},
traits::Externalities,
};
use sc_executor_common::{runtime_blob::RuntimeBlob, wasm_runtime::WasmModule};
use sc_runtime_test::wasm_binary_unwrap;
use sp_state_machine::TestExternalities as CoreTestExternalities;
use sp_trie::{TrieConfiguration, trie_types::Layout};
use sp_wasm_interface::HostFunctions as _;
use sp_core::{
blake2_128, blake2_256, ed25519, map,
offchain::{testing, OffchainDbExt, OffchainWorkerExt},
sr25519,
traits::Externalities,
Pair,
};
use sp_runtime::traits::BlakeTwo256;
use sc_executor_common::{wasm_runtime::WasmModule, runtime_blob::RuntimeBlob};
use sp_state_machine::TestExternalities as CoreTestExternalities;
use sp_trie::{trie_types::Layout, TrieConfiguration};
use sp_wasm_interface::HostFunctions as _;
use std::sync::Arc;
use tracing_subscriber::layer::SubscriberExt;
use crate::WasmExecutionMethod;
@@ -96,12 +98,7 @@ fn returning_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let output = call_in_wasm(
"test_empty_return",
&[],
wasm_method,
&mut ext,
).unwrap();
let output = call_in_wasm("test_empty_return", &[], wasm_method, &mut ext).unwrap();
assert_eq!(output, vec![0u8; 0]);
}
@@ -164,28 +161,13 @@ fn panicking_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let output = call_in_wasm(
"test_panic",
&[],
wasm_method,
&mut ext,
);
let output = call_in_wasm("test_panic", &[], wasm_method, &mut ext);
assert!(output.is_err());
let output = call_in_wasm(
"test_conditional_panic",
&[0],
wasm_method,
&mut ext,
);
let output = call_in_wasm("test_conditional_panic", &[0], wasm_method, &mut ext);
assert_eq!(Decode::decode(&mut &output.unwrap()[..]), Ok(Vec::<u8>::new()));
let output = call_in_wasm(
"test_conditional_panic",
&vec![2].encode(),
wasm_method,
&mut ext,
);
let output = call_in_wasm("test_conditional_panic", &vec![2].encode(), wasm_method, &mut ext);
assert!(output.is_err());
}
@@ -197,12 +179,9 @@ fn storage_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = ext.ext();
ext.set_storage(b"foo".to_vec(), b"bar".to_vec());
let output = call_in_wasm(
"test_data_in",
&b"Hello world".to_vec().encode(),
wasm_method,
&mut ext,
).unwrap();
let output =
call_in_wasm("test_data_in", &b"Hello world".to_vec().encode(), wasm_method, &mut ext)
.unwrap();
assert_eq!(output, b"all ok!".to_vec().encode());
}
@@ -230,12 +209,9 @@ fn clear_prefix_should_work(wasm_method: WasmExecutionMethod) {
ext.set_storage(b"bbb".to_vec(), b"5".to_vec());
// This will clear all entries which prefix is "ab".
let output = call_in_wasm(
"test_clear_prefix",
&b"ab".to_vec().encode(),
wasm_method,
&mut ext,
).unwrap();
let output =
call_in_wasm("test_clear_prefix", &b"ab".to_vec().encode(), wasm_method, &mut ext)
.unwrap();
assert_eq!(output, b"all ok!".to_vec().encode());
}
@@ -256,21 +232,12 @@ fn blake2_256_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
assert_eq!(
call_in_wasm(
"test_blake2_256",
&[0],
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_blake2_256", &[0], wasm_method, &mut ext,).unwrap(),
blake2_256(&b""[..]).to_vec().encode(),
);
assert_eq!(
call_in_wasm(
"test_blake2_256",
&b"Hello world!".to_vec().encode(),
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_blake2_256", &b"Hello world!".to_vec().encode(), wasm_method, &mut ext,)
.unwrap(),
blake2_256(&b"Hello world!"[..]).to_vec().encode(),
);
}
@@ -280,21 +247,12 @@ fn blake2_128_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
assert_eq!(
call_in_wasm(
"test_blake2_128",
&[0],
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_blake2_128", &[0], wasm_method, &mut ext,).unwrap(),
blake2_128(&b""[..]).to_vec().encode(),
);
assert_eq!(
call_in_wasm(
"test_blake2_128",
&b"Hello world!".to_vec().encode(),
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_blake2_128", &b"Hello world!".to_vec().encode(), wasm_method, &mut ext,)
.unwrap(),
blake2_128(&b"Hello world!"[..]).to_vec().encode(),
);
}
@@ -304,25 +262,14 @@ fn sha2_256_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
assert_eq!(
call_in_wasm(
"test_sha2_256",
&[0],
wasm_method,
&mut ext,
)
.unwrap(),
call_in_wasm("test_sha2_256", &[0], wasm_method, &mut ext,).unwrap(),
hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
.to_vec()
.encode(),
);
assert_eq!(
call_in_wasm(
"test_sha2_256",
&b"Hello world!".to_vec().encode(),
wasm_method,
&mut ext,
)
.unwrap(),
call_in_wasm("test_sha2_256", &b"Hello world!".to_vec().encode(), wasm_method, &mut ext,)
.unwrap(),
hex!("c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a")
.to_vec()
.encode(),
@@ -334,26 +281,17 @@ fn twox_256_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
assert_eq!(
call_in_wasm(
"test_twox_256",
&[0],
wasm_method,
&mut ext,
).unwrap(),
hex!(
"99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a"
).to_vec().encode(),
call_in_wasm("test_twox_256", &[0], wasm_method, &mut ext,).unwrap(),
hex!("99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a")
.to_vec()
.encode(),
);
assert_eq!(
call_in_wasm(
"test_twox_256",
&b"Hello world!".to_vec().encode(),
wasm_method,
&mut ext,
).unwrap(),
hex!(
"b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74"
).to_vec().encode(),
call_in_wasm("test_twox_256", &b"Hello world!".to_vec().encode(), wasm_method, &mut ext,)
.unwrap(),
hex!("b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74")
.to_vec()
.encode(),
);
}
@@ -362,21 +300,12 @@ fn twox_128_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
assert_eq!(
call_in_wasm(
"test_twox_128",
&[0],
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_twox_128", &[0], wasm_method, &mut ext,).unwrap(),
hex!("99e9d85137db46ef4bbea33613baafd5").to_vec().encode(),
);
assert_eq!(
call_in_wasm(
"test_twox_128",
&b"Hello world!".to_vec().encode(),
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_twox_128", &b"Hello world!".to_vec().encode(), wasm_method, &mut ext,)
.unwrap(),
hex!("b27dfd7f223f177f2a13647b533599af").to_vec().encode(),
);
}
@@ -392,12 +321,7 @@ fn ed25519_verify_should_work(wasm_method: WasmExecutionMethod) {
calldata.extend_from_slice(sig.as_ref());
assert_eq!(
call_in_wasm(
"test_ed25519_verify",
&calldata.encode(),
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_ed25519_verify", &calldata.encode(), wasm_method, &mut ext,).unwrap(),
true.encode(),
);
@@ -407,12 +331,7 @@ fn ed25519_verify_should_work(wasm_method: WasmExecutionMethod) {
calldata.extend_from_slice(other_sig.as_ref());
assert_eq!(
call_in_wasm(
"test_ed25519_verify",
&calldata.encode(),
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_ed25519_verify", &calldata.encode(), wasm_method, &mut ext,).unwrap(),
false.encode(),
);
}
@@ -428,12 +347,7 @@ fn sr25519_verify_should_work(wasm_method: WasmExecutionMethod) {
calldata.extend_from_slice(sig.as_ref());
assert_eq!(
call_in_wasm(
"test_sr25519_verify",
&calldata.encode(),
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sr25519_verify", &calldata.encode(), wasm_method, &mut ext,).unwrap(),
true.encode(),
);
@@ -443,12 +357,7 @@ fn sr25519_verify_should_work(wasm_method: WasmExecutionMethod) {
calldata.extend_from_slice(other_sig.as_ref());
assert_eq!(
call_in_wasm(
"test_sr25519_verify",
&calldata.encode(),
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sr25519_verify", &calldata.encode(), wasm_method, &mut ext,).unwrap(),
false.encode(),
);
}
@@ -458,12 +367,7 @@ fn ordered_trie_root_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()];
assert_eq!(
call_in_wasm(
"test_ordered_trie_root",
&[0],
wasm_method,
&mut ext.ext(),
).unwrap(),
call_in_wasm("test_ordered_trie_root", &[0], wasm_method, &mut ext.ext(),).unwrap(),
Layout::<BlakeTwo256>::ordered_trie_root(trie_input.iter()).as_bytes().encode(),
);
}
@@ -473,17 +377,14 @@ fn offchain_index(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let (offchain, _state) = testing::TestOffchainExt::new();
ext.register_extension(OffchainWorkerExt::new(offchain));
call_in_wasm(
"test_offchain_index_set",
&[0],
wasm_method,
&mut ext.ext(),
).unwrap();
call_in_wasm("test_offchain_index_set", &[0], wasm_method, &mut ext.ext()).unwrap();
use sp_core::offchain::OffchainOverlayedChange;
let data = ext.overlayed_changes().clone().offchain_drain_committed().find(|(k, _v)| {
k == &(sp_core::offchain::STORAGE_PREFIX.to_vec(), b"k".to_vec())
});
let data = ext
.overlayed_changes()
.clone()
.offchain_drain_committed()
.find(|(k, _v)| k == &(sp_core::offchain::STORAGE_PREFIX.to_vec(), b"k".to_vec()));
assert_eq!(data.map(|data| data.1), Some(OffchainOverlayedChange::SetValue(b"v".to_vec())));
}
@@ -494,12 +395,7 @@ fn offchain_local_storage_should_work(wasm_method: WasmExecutionMethod) {
ext.register_extension(OffchainDbExt::new(offchain.clone()));
ext.register_extension(OffchainWorkerExt::new(offchain));
assert_eq!(
call_in_wasm(
"test_offchain_local_storage",
&[0],
wasm_method,
&mut ext.ext(),
).unwrap(),
call_in_wasm("test_offchain_local_storage", &[0], wasm_method, &mut ext.ext(),).unwrap(),
true.encode(),
);
assert_eq!(state.read().persistent_storage.get(b"test"), Some(vec![]));
@@ -511,24 +407,18 @@ fn offchain_http_should_work(wasm_method: WasmExecutionMethod) {
let (offchain, state) = testing::TestOffchainExt::new();
ext.register_extension(OffchainWorkerExt::new(offchain));
state.write().expect_request(testing::PendingRequest {
method: "POST".into(),
uri: "http://localhost:12345".into(),
body: vec![1, 2, 3, 4],
headers: vec![("X-Auth".to_owned(), "test".to_owned())],
sent: true,
response: Some(vec![1, 2, 3]),
response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())],
..Default::default()
},
);
method: "POST".into(),
uri: "http://localhost:12345".into(),
body: vec![1, 2, 3, 4],
headers: vec![("X-Auth".to_owned(), "test".to_owned())],
sent: true,
response: Some(vec![1, 2, 3]),
response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())],
..Default::default()
});
assert_eq!(
call_in_wasm(
"test_offchain_http",
&[0],
wasm_method,
&mut ext.ext(),
).unwrap(),
call_in_wasm("test_offchain_http", &[0], wasm_method, &mut ext.ext(),).unwrap(),
true.encode(),
);
}
@@ -539,7 +429,7 @@ fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) {
let executor = crate::WasmExecutor::new(
wasm_method,
Some(17), // `17` is the initial number of pages compiled into the binary.
Some(17), // `17` is the initial number of pages compiled into the binary.
HostFunctions::host_functions(),
8,
None,
@@ -593,17 +483,13 @@ fn returns_mutable_static_bss(wasm_method: WasmExecutionMethod) {
let runtime = mk_test_runtime(wasm_method, 1024);
let instance = runtime.new_instance().unwrap();
let res = instance
.call_export("returns_mutable_static_bss", &[0])
.unwrap();
let res = instance.call_export("returns_mutable_static_bss", &[0]).unwrap();
assert_eq!(1, u64::decode(&mut &res[..]).unwrap());
// We expect that every invocation will need to return the initial
// value plus one. If the value increases more than that then it is
// a sign that the wasm runtime preserves the memory content.
let res = instance
.call_export("returns_mutable_static_bss", &[0])
.unwrap();
let res = instance.call_export("returns_mutable_static_bss", &[0]).unwrap();
assert_eq!(1, u64::decode(&mut &res[..]).unwrap());
}
@@ -638,7 +524,8 @@ fn heap_is_reset_between_calls(wasm_method: WasmExecutionMethod) {
let runtime = mk_test_runtime(wasm_method, 1024);
let instance = runtime.new_instance().unwrap();
let heap_base = instance.get_global_const("__heap_base")
let heap_base = instance
.get_global_const("__heap_base")
.expect("`__heap_base` is valid")
.expect("`__heap_base` exists")
.as_i32()
@@ -689,8 +576,8 @@ fn parallel_execution(wasm_method: WasmExecutionMethod) {
test_wasm_execution!(wasm_tracing_should_work);
fn wasm_tracing_should_work(wasm_method: WasmExecutionMethod) {
use std::sync::Mutex;
use sc_tracing::{SpanDatum, TraceEvent};
use std::sync::Mutex;
struct TestTraceHandler(Arc<Mutex<Vec<SpanDatum>>>);
@@ -706,36 +593,23 @@ fn wasm_tracing_should_work(wasm_method: WasmExecutionMethod) {
let handler = TestTraceHandler(traces.clone());
// Create subscriber with wasm_tracing disabled
let test_subscriber = tracing_subscriber::fmt().finish().with(
sc_tracing::ProfilingLayer::new_with_handler(
Box::new(handler), "default"
)
);
let test_subscriber = tracing_subscriber::fmt()
.finish()
.with(sc_tracing::ProfilingLayer::new_with_handler(Box::new(handler), "default"));
let _guard = tracing::subscriber::set_default(test_subscriber);
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let span_id = call_in_wasm(
"test_enter_span",
Default::default(),
wasm_method,
&mut ext,
).unwrap();
let span_id =
call_in_wasm("test_enter_span", Default::default(), wasm_method, &mut ext).unwrap();
let span_id = u64::decode(&mut &span_id[..]).unwrap();
assert!(
span_id > 0
);
assert!(span_id > 0);
call_in_wasm(
"test_exit_span",
&span_id.encode(),
wasm_method,
&mut ext,
).unwrap();
call_in_wasm("test_exit_span", &span_id.encode(), wasm_method, &mut ext).unwrap();
// Check there is only the single trace
let len = traces.lock().unwrap().len();
@@ -747,12 +621,7 @@ fn wasm_tracing_should_work(wasm_method: WasmExecutionMethod) {
assert_eq!(span_datum.name, "");
assert_eq!(values.bool_values.get("wasm").unwrap(), &true);
call_in_wasm(
"test_nested_spans",
Default::default(),
wasm_method,
&mut ext,
).unwrap();
call_in_wasm("test_nested_spans", Default::default(), wasm_method, &mut ext).unwrap();
let len = traces.lock().unwrap().len();
assert_eq!(len, 2);
}
@@ -762,12 +631,7 @@ fn spawning_runtime_instance_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
call_in_wasm(
"test_spawn",
&[],
wasm_method,
&mut ext,
).unwrap();
call_in_wasm("test_spawn", &[], wasm_method, &mut ext).unwrap();
}
test_wasm_execution!(spawning_runtime_instance_nested_should_work);
@@ -775,12 +639,7 @@ fn spawning_runtime_instance_nested_should_work(wasm_method: WasmExecutionMethod
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
call_in_wasm(
"test_nested_spawn",
&[],
wasm_method,
&mut ext,
).unwrap();
call_in_wasm("test_nested_spawn", &[], wasm_method, &mut ext).unwrap();
}
test_wasm_execution!(panic_in_spawned_instance_panics_on_joining_its_result);
@@ -788,12 +647,8 @@ fn panic_in_spawned_instance_panics_on_joining_its_result(wasm_method: WasmExecu
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let error_result = call_in_wasm(
"test_panic_in_spawned",
&[],
wasm_method,
&mut ext,
).unwrap_err();
let error_result =
call_in_wasm("test_panic_in_spawned", &[], wasm_method, &mut ext).unwrap_err();
assert!(format!("{}", error_result).contains("Spawned task"));
}
@@ -16,9 +16,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use super::{TestExternalities, call_in_wasm};
use crate::WasmExecutionMethod;
use crate::test_wasm_execution;
use super::{call_in_wasm, TestExternalities};
use crate::{test_wasm_execution, WasmExecutionMethod};
use codec::Encode;
@@ -27,7 +26,8 @@ fn sandbox_should_work(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(import "env" "assert" (func $assert (param i32)))
(import "env" "inc_counter" (func $inc_counter (param i32) (result i32)))
@@ -46,17 +46,12 @@ fn sandbox_should_work(wasm_method: WasmExecutionMethod) {
call $assert
)
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox",
&code,
wasm_method,
&mut ext,
).unwrap(),
true.encode(),
);
assert_eq!(call_in_wasm("test_sandbox", &code, wasm_method, &mut ext,).unwrap(), true.encode(),);
}
test_wasm_execution!(sandbox_trap);
@@ -64,7 +59,8 @@ fn sandbox_trap(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(import "env" "assert" (func $assert (param i32)))
(func (export "call")
@@ -72,17 +68,11 @@ fn sandbox_trap(wasm_method: WasmExecutionMethod) {
call $assert
)
)
"#).unwrap();
"#,
)
.unwrap();
assert_eq!(
call_in_wasm(
"test_sandbox",
&code,
wasm_method,
&mut ext,
).unwrap(),
vec![0],
);
assert_eq!(call_in_wasm("test_sandbox", &code, wasm_method, &mut ext,).unwrap(), vec![0],);
}
test_wasm_execution!(start_called);
@@ -90,7 +80,8 @@ fn start_called(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(import "env" "assert" (func $assert (param i32)))
(import "env" "inc_counter" (func $inc_counter (param i32) (result i32)))
@@ -115,17 +106,12 @@ fn start_called(wasm_method: WasmExecutionMethod) {
call $assert
)
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox",
&code,
wasm_method,
&mut ext,
).unwrap(),
true.encode(),
);
assert_eq!(call_in_wasm("test_sandbox", &code, wasm_method, &mut ext,).unwrap(), true.encode(),);
}
test_wasm_execution!(invoke_args);
@@ -133,7 +119,8 @@ fn invoke_args(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(import "env" "assert" (func $assert (param i32)))
@@ -154,15 +141,13 @@ fn invoke_args(wasm_method: WasmExecutionMethod) {
)
)
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox_args",
&code,
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sandbox_args", &code, wasm_method, &mut ext,).unwrap(),
true.encode(),
);
}
@@ -172,7 +157,8 @@ fn return_val(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(func (export "call") (param $x i32) (result i32)
(i32.add
@@ -181,15 +167,13 @@ fn return_val(wasm_method: WasmExecutionMethod) {
)
)
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox_return_val",
&code,
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sandbox_return_val", &code, wasm_method, &mut ext,).unwrap(),
true.encode(),
);
}
@@ -199,22 +183,21 @@ fn unlinkable_module(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(import "env" "non-existent" (func))
(func (export "call")
)
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox_instantiate",
&code,
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sandbox_instantiate", &code, wasm_method, &mut ext,).unwrap(),
1u8.encode(),
);
}
@@ -228,12 +211,7 @@ fn corrupted_module(wasm_method: WasmExecutionMethod) {
let code = vec![0u8, 0, 0, 0, 1, 0, 0, 0].encode();
assert_eq!(
call_in_wasm(
"test_sandbox_instantiate",
&code,
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sandbox_instantiate", &code, wasm_method, &mut ext,).unwrap(),
1u8.encode(),
);
}
@@ -243,7 +221,8 @@ fn start_fn_ok(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(func (export "call")
)
@@ -253,15 +232,13 @@ fn start_fn_ok(wasm_method: WasmExecutionMethod) {
(start $start)
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox_instantiate",
&code,
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sandbox_instantiate", &code, wasm_method, &mut ext,).unwrap(),
0u8.encode(),
);
}
@@ -271,7 +248,8 @@ fn start_fn_traps(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(func (export "call")
)
@@ -282,15 +260,13 @@ fn start_fn_traps(wasm_method: WasmExecutionMethod) {
(start $start)
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox_instantiate",
&code,
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sandbox_instantiate", &code, wasm_method, &mut ext,).unwrap(),
2u8.encode(),
);
}
@@ -300,19 +276,18 @@ fn get_global_val_works(wasm_method: WasmExecutionMethod) {
let mut ext = TestExternalities::default();
let mut ext = ext.ext();
let code = wat::parse_str(r#"
let code = wat::parse_str(
r#"
(module
(global (export "test_global") i64 (i64.const 500))
)
"#).unwrap().encode();
"#,
)
.unwrap()
.encode();
assert_eq!(
call_in_wasm(
"test_sandbox_get_global_val",
&code,
wasm_method,
&mut ext,
).unwrap(),
call_in_wasm("test_sandbox_get_global_val", &code, wasm_method, &mut ext,).unwrap(),
500i64.encode(),
);
}
+10 -11
View File
@@ -29,26 +29,25 @@
//! wasm engine used, instance cache.
#![warn(missing_docs)]
#![recursion_limit="128"]
#![recursion_limit = "128"]
#[macro_use]
mod native_executor;
mod wasm_runtime;
#[cfg(test)]
mod integration_tests;
mod wasm_runtime;
pub use wasmi;
pub use native_executor::{
with_externalities_safe, NativeExecutor, WasmExecutor, NativeExecutionDispatch,
};
pub use sp_version::{RuntimeVersion, NativeVersion};
pub use codec::Codec;
pub use native_executor::{
with_externalities_safe, NativeExecutionDispatch, NativeExecutor, WasmExecutor,
};
#[doc(hidden)]
pub use sp_core::traits::{Externalities};
pub use sp_core::traits::Externalities;
pub use sp_version::{NativeVersion, RuntimeVersion};
#[doc(hidden)]
pub use sp_wasm_interface;
pub use wasm_runtime::WasmExecutionMethod;
pub use wasm_runtime::read_embedded_version;
pub use wasm_runtime::{read_embedded_version, WasmExecutionMethod};
pub use wasmi;
pub use sc_executor_common::{error, sandbox};
@@ -68,10 +67,10 @@ pub trait RuntimeInfo {
#[cfg(test)]
mod tests {
use super::*;
use sc_executor_common::runtime_blob::RuntimeBlob;
use sc_runtime_test::wasm_binary_unwrap;
use sp_io::TestExternalities;
use sp_wasm_interface::HostFunctions;
use sc_executor_common::runtime_blob::RuntimeBlob;
#[test]
fn call_in_interpreted_wasm_works() {
+106 -132
View File
@@ -17,32 +17,36 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{
RuntimeInfo, error::{Error, Result},
error::{Error, Result},
wasm_runtime::{RuntimeCache, WasmExecutionMethod},
RuntimeInfo,
};
use std::{
collections::HashMap,
panic::{UnwindSafe, AssertUnwindSafe},
result,
sync::{Arc, atomic::{AtomicU64, Ordering}, mpsc},
panic::{AssertUnwindSafe, UnwindSafe},
path::PathBuf,
result,
sync::{
atomic::{AtomicU64, Ordering},
mpsc, Arc,
},
};
use sp_version::{NativeVersion, RuntimeVersion};
use codec::{Decode, Encode};
use sp_core::{
NativeOrEncoded,
traits::{CodeExecutor, Externalities, RuntimeCode, RuntimeSpawnExt, RuntimeSpawn},
};
use log::trace;
use sp_wasm_interface::{HostFunctions, Function};
use sc_executor_common::{
wasm_runtime::{WasmInstance, WasmModule, InvokeMethod},
runtime_blob::RuntimeBlob,
wasm_runtime::{InvokeMethod, WasmInstance, WasmModule},
};
use sp_core::{
traits::{CodeExecutor, Externalities, RuntimeCode, RuntimeSpawn, RuntimeSpawnExt},
NativeOrEncoded,
};
use sp_externalities::ExternalitiesExt as _;
use sp_tasks::new_async_externalities;
use sp_version::{NativeVersion, RuntimeVersion};
use sp_wasm_interface::{Function, HostFunctions};
/// Default num of pages for the heap
const DEFAULT_HEAP_PAGES: u64 = 2048;
@@ -51,25 +55,23 @@ const DEFAULT_HEAP_PAGES: u64 = 2048;
///
/// If the inner closure panics, it will be caught and return an error.
pub fn with_externalities_safe<F, U>(ext: &mut dyn Externalities, f: F) -> Result<U>
where F: UnwindSafe + FnOnce() -> U
where
F: UnwindSafe + FnOnce() -> U,
{
sp_externalities::set_and_run_with_externalities(
ext,
move || {
// Substrate uses custom panic hook that terminates process on panic. Disable
// termination for the native call.
let _guard = sp_panic_handler::AbortGuard::force_unwind();
std::panic::catch_unwind(f).map_err(|e| {
if let Some(err) = e.downcast_ref::<String>() {
Error::RuntimePanicked(err.clone())
} else if let Some(err) = e.downcast_ref::<&'static str>() {
Error::RuntimePanicked(err.to_string())
} else {
Error::RuntimePanicked("Unknown panic".into())
}
})
},
)
sp_externalities::set_and_run_with_externalities(ext, move || {
// Substrate uses custom panic hook that terminates process on panic. Disable
// termination for the native call.
let _guard = sp_panic_handler::AbortGuard::force_unwind();
std::panic::catch_unwind(f).map_err(|e| {
if let Some(err) = e.downcast_ref::<String>() {
Error::RuntimePanicked(err.clone())
} else if let Some(err) = e.downcast_ref::<&'static str>() {
Error::RuntimePanicked(err.to_string())
} else {
Error::RuntimePanicked("Unknown panic".into())
}
})
})
}
/// Delegate for dispatching a CodeExecutor call.
@@ -163,7 +165,8 @@ impl WasmExecutor {
allow_missing_host_functions: bool,
f: F,
) -> Result<R>
where F: FnOnce(
where
F: FnOnce(
AssertUnwindSafe<&Arc<dyn WasmModule>>,
AssertUnwindSafe<&dyn WasmInstance>,
Option<&RuntimeVersion>,
@@ -182,7 +185,7 @@ impl WasmExecutor {
let instance = AssertUnwindSafe(instance);
let ext = AssertUnwindSafe(ext);
f(module, instance, version, ext)
}
},
)? {
Ok(r) => r,
Err(e) => Err(e),
@@ -245,7 +248,7 @@ impl sp_core::traits::ReadRuntimeVersion for WasmExecutor {
.map_err(|e| format!("Failed to read the static section: {:?}", e))
.map(|v| v.map(|v| v.encode()))?
{
return Ok(version);
return Ok(version)
}
// If the blob didn't have embedded runtime version section, we fallback to the legacy
@@ -296,13 +299,13 @@ impl<D: NativeExecutionDispatch> NativeExecutor<D> {
.into_iter()
// filter out any host function overrides provided.
.filter(|host_fn| {
extended.iter()
extended
.iter()
.find(|ext_host_fn| host_fn.name() == ext_host_fn.name())
.is_none()
})
.collect::<Vec<_>>();
// Add the custom host functions provided by the user.
host_functions.extend(extended);
let wasm_executor = WasmExecutor::new(
@@ -331,13 +334,10 @@ impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
ext: &mut dyn Externalities,
runtime_code: &RuntimeCode,
) -> Result<RuntimeVersion> {
self.wasm.with_instance(
runtime_code,
ext,
false,
|_module, _instance, version, _ext|
Ok(version.cloned().ok_or_else(|| Error::ApiError("Unknown version".into()))),
)
self.wasm
.with_instance(runtime_code, ext, false, |_module, _instance, version, _ext| {
Ok(version.cloned().ok_or_else(|| Error::ApiError("Unknown version".into())))
})
}
}
@@ -358,70 +358,67 @@ impl RuntimeSpawn for RuntimeInstanceSpawn {
let module = self.module.clone();
let scheduler = self.scheduler.clone();
self.scheduler.spawn("executor-extra-runtime-instance", Box::pin(async move {
let module = AssertUnwindSafe(module);
self.scheduler.spawn(
"executor-extra-runtime-instance",
Box::pin(async move {
let module = AssertUnwindSafe(module);
let async_ext = match new_async_externalities(scheduler.clone()) {
Ok(val) => val,
Err(e) => {
log::error!(
target: "executor",
"Failed to setup externalities for async context: {}",
e,
);
let async_ext = match new_async_externalities(scheduler.clone()) {
Ok(val) => val,
Err(e) => {
log::error!(
target: "executor",
"Failed to setup externalities for async context: {}",
e,
);
// This will drop sender and receiver end will panic
return;
}
};
// This will drop sender and receiver end will panic
return
},
};
let mut async_ext = match async_ext.with_runtime_spawn(
Box::new(RuntimeInstanceSpawn::new(module.clone(), scheduler))
) {
Ok(val) => val,
Err(e) => {
log::error!(
target: "executor",
"Failed to setup runtime extension for async externalities: {}",
e,
);
let mut async_ext = match async_ext.with_runtime_spawn(Box::new(
RuntimeInstanceSpawn::new(module.clone(), scheduler),
)) {
Ok(val) => val,
Err(e) => {
log::error!(
target: "executor",
"Failed to setup runtime extension for async externalities: {}",
e,
);
// This will drop sender and receiver end will panic
return;
}
};
let result = with_externalities_safe(
&mut async_ext,
move || {
// This will drop sender and receiver end will panic
return
},
};
let result = with_externalities_safe(&mut async_ext, move || {
// FIXME: Should be refactored to shared "instance factory".
// Instantiating wasm here every time is suboptimal at the moment, shared
// pool of instances should be used.
//
// https://github.com/paritytech/substrate/issues/7354
let instance = module.new_instance()
.expect("Failed to create new instance from module");
let instance =
module.new_instance().expect("Failed to create new instance from module");
instance.call(
InvokeMethod::TableWithWrapper { dispatcher_ref, func },
&data[..],
).expect("Failed to invoke instance.")
instance
.call(InvokeMethod::TableWithWrapper { dispatcher_ref, func }, &data[..])
.expect("Failed to invoke instance.")
});
match result {
Ok(output) => {
let _ = sender.send(output);
},
Err(error) => {
// If execution is panicked, the `join` in the original runtime code will panic as well,
// since the sender is dropped without sending anything.
log::error!("Call error in spawned task: {:?}", error);
},
}
);
match result {
Ok(output) => {
let _ = sender.send(output);
},
Err(error) => {
// If execution is panicked, the `join` in the original runtime code will panic as well,
// since the sender is dropped without sending anything.
log::error!("Call error in spawned task: {:?}", error);
},
}
}));
}),
);
new_handle
}
@@ -438,12 +435,7 @@ impl RuntimeInstanceSpawn {
module: Arc<dyn WasmModule>,
scheduler: Box<dyn sp_core::traits::SpawnNamed>,
) -> Self {
Self {
module,
scheduler,
counter: 0.into(),
tasks: HashMap::new().into(),
}
Self { module, scheduler, counter: 0.into(), tasks: HashMap::new().into() }
}
fn with_externalities_and_module(
@@ -495,17 +487,13 @@ impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeExecutor<D> {
ext,
false,
|module, instance, onchain_version, mut ext| {
let onchain_version = onchain_version.ok_or_else(
|| Error::ApiError("Unknown version".into())
)?;
let onchain_version =
onchain_version.ok_or_else(|| Error::ApiError("Unknown version".into()))?;
let can_call_with = onchain_version.can_call_with(&self.native_version.runtime_version);
let can_call_with =
onchain_version.can_call_with(&self.native_version.runtime_version);
match (
use_native,
can_call_with,
native_call,
) {
match (use_native, can_call_with, native_call) {
(_, false, _) | (false, _, _) => {
if !can_call_with {
trace!(
@@ -516,13 +504,10 @@ impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeExecutor<D> {
);
}
with_externalities_safe(
&mut **ext,
move || {
preregister_builtin_ext(module.clone());
instance.call_export(method, data).map(NativeOrEncoded::Encoded)
}
)
with_externalities_safe(&mut **ext, move || {
preregister_builtin_ext(module.clone());
instance.call_export(method, data).map(NativeOrEncoded::Encoded)
})
},
(true, true, Some(call)) => {
trace!(
@@ -535,13 +520,10 @@ impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeExecutor<D> {
used_native = true;
let res = with_externalities_safe(&mut **ext, move || (call)())
.and_then(|r| r
.map(NativeOrEncoded::Native)
.map_err(Error::ApiError)
);
.and_then(|r| r.map(NativeOrEncoded::Native).map_err(Error::ApiError));
Ok(res)
}
},
_ => {
trace!(
target: "executor",
@@ -552,9 +534,9 @@ impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeExecutor<D> {
used_native = true;
Ok(D::dispatch(&mut **ext, method, data).map(NativeOrEncoded::Encoded))
}
},
}
}
},
);
(result, used_native)
}
@@ -617,7 +599,6 @@ impl<D: NativeExecutionDispatch> sp_core::traits::ReadRuntimeVersion for NativeE
///
/// When you have multiple interfaces, you can give the host functions as a tuple e.g.:
/// `(my_interface::HostFunctions, my_interface2::HostFunctions)`
///
#[macro_export]
macro_rules! native_executor_instance {
( $pub:vis $name:ident, $dispatcher:path, $version:path $(,)?) => {
@@ -675,16 +656,9 @@ mod tests {
#[test]
fn native_executor_registers_custom_interface() {
let executor = NativeExecutor::<MyExecutor>::new(
WasmExecutionMethod::Interpreted,
None,
8,
);
let executor = NativeExecutor::<MyExecutor>::new(WasmExecutionMethod::Interpreted, None, 8);
my_interface::HostFunctions::host_functions().iter().for_each(|function| {
assert_eq!(
executor.wasm.host_functions.iter().filter(|f| f == &function).count(),
2,
);
assert_eq!(executor.wasm.host_functions.iter().filter(|f| f == &function).count(), 2,);
});
my_interface::say_hello_world("hey");
+82 -99
View File
@@ -21,17 +21,19 @@
//! The primary means of accessing the runtimes is through a cache which saves the reusable
//! components of the runtime that are expensive to initialize.
use std::sync::Arc;
use crate::error::{Error, WasmError};
use parking_lot::Mutex;
use codec::Decode;
use sp_core::traits::{Externalities, RuntimeCode, FetchRuntimeCode};
use sp_version::RuntimeVersion;
use std::panic::AssertUnwindSafe;
use std::path::{Path, PathBuf};
use parking_lot::Mutex;
use sc_executor_common::{
wasm_runtime::{WasmModule, WasmInstance},
runtime_blob::RuntimeBlob,
wasm_runtime::{WasmInstance, WasmModule},
};
use sp_core::traits::{Externalities, FetchRuntimeCode, RuntimeCode};
use sp_version::RuntimeVersion;
use std::{
panic::AssertUnwindSafe,
path::{Path, PathBuf},
sync::Arc,
};
use sp_wasm_interface::Function;
@@ -70,27 +72,26 @@ struct VersionedRuntime {
impl VersionedRuntime {
/// Run the given closure `f` with an instance of this runtime.
fn with_instance<'c, R, F>(
&self,
ext: &mut dyn Externalities,
f: F,
) -> Result<R, Error>
where F: FnOnce(
fn with_instance<'c, R, F>(&self, ext: &mut dyn Externalities, f: F) -> Result<R, Error>
where
F: FnOnce(
&Arc<dyn WasmModule>,
&dyn WasmInstance,
Option<&RuntimeVersion>,
&mut dyn Externalities)
-> Result<R, Error>,
&mut dyn Externalities,
) -> Result<R, Error>,
{
// Find a free instance
let instance = self.instances
let instance = self
.instances
.iter()
.enumerate()
.find_map(|(index, i)| i.try_lock().map(|i| (index, i)));
match instance {
Some((index, mut locked)) => {
let (instance, new_inst) = locked.take()
let (instance, new_inst) = locked
.take()
.map(|r| Ok((r, false)))
.unwrap_or_else(|| self.module.new_instance().map(|i| (i, true)))?;
@@ -131,7 +132,7 @@ impl VersionedRuntime {
let instance = self.module.new_instance()?;
f(&self.module, &*instance, self.version.as_ref(), ext)
}
},
}
}
}
@@ -168,11 +169,7 @@ impl RuntimeCache {
/// `cache_path` allows to specify an optional directory where the executor can store files
/// for caching.
pub fn new(max_runtime_instances: usize, cache_path: Option<PathBuf>) -> RuntimeCache {
RuntimeCache {
runtimes: Default::default(),
max_runtime_instances,
cache_path,
}
RuntimeCache { runtimes: Default::default(), max_runtime_instances, cache_path }
}
/// Prepares a WASM module instance and executes given function for it.
@@ -213,29 +210,31 @@ impl RuntimeCache {
allow_missing_func_imports: bool,
f: F,
) -> Result<Result<R, Error>, Error>
where F: FnOnce(
where
F: FnOnce(
&Arc<dyn WasmModule>,
&dyn WasmInstance,
Option<&RuntimeVersion>,
&mut dyn Externalities)
-> Result<R, Error>,
&mut dyn Externalities,
) -> Result<R, Error>,
{
let code_hash = &runtime_code.hash;
let heap_pages = runtime_code.heap_pages.unwrap_or(default_heap_pages);
let mut runtimes = self.runtimes.lock(); // this must be released prior to calling f
let pos = runtimes.iter().position(|r| r.as_ref().map_or(
false,
|r| r.wasm_method == wasm_method &&
r.code_hash == *code_hash &&
r.heap_pages == heap_pages
));
let pos = runtimes.iter().position(|r| {
r.as_ref().map_or(false, |r| {
r.wasm_method == wasm_method &&
r.code_hash == *code_hash &&
r.heap_pages == heap_pages
})
});
let runtime = match pos {
Some(n) => runtimes[n]
.clone()
.expect("`position` only returns `Some` for entries that are `Some`"),
None => {
None => {
let code = runtime_code.fetch_runtime_code().ok_or(WasmError::CodeNotFound)?;
#[cfg(not(target_os = "unknown"))]
@@ -262,30 +261,29 @@ impl RuntimeCache {
result.version,
time.elapsed().as_millis(),
);
}
},
Err(ref err) => {
log::warn!(target: "wasm-runtime", "Cannot create a runtime: {:?}", err);
}
},
}
Arc::new(result?)
}
},
};
// Rearrange runtimes by last recently used.
match pos {
Some(0) => {},
Some(n) => {
for i in (1 .. n + 1).rev() {
Some(n) =>
for i in (1..n + 1).rev() {
runtimes.swap(i, i - 1);
}
}
},
None => {
runtimes[MAX_RUNTIMES-1] = Some(runtime.clone());
for i in (1 .. MAX_RUNTIMES).rev() {
runtimes[MAX_RUNTIMES - 1] = Some(runtime.clone());
for i in (1..MAX_RUNTIMES).rev() {
runtimes.swap(i, i - 1);
}
}
},
}
drop(runtimes);
@@ -317,49 +315,48 @@ pub fn create_wasm_runtime_with_code(
allow_missing_func_imports,
)
.map(|runtime| -> Arc<dyn WasmModule> { Arc::new(runtime) })
}
#[cfg(feature = "wasmtime")]
WasmExecutionMethod::Compiled => {
sc_executor_wasmtime::create_runtime(
blob,
sc_executor_wasmtime::Config {
heap_pages: heap_pages as u32,
allow_missing_func_imports,
cache_path: cache_path.map(ToOwned::to_owned),
semantics: sc_executor_wasmtime::Semantics {
fast_instance_reuse: true,
deterministic_stack_limit: None,
canonicalize_nans: false,
},
},
host_functions,
).map(|runtime| -> Arc<dyn WasmModule> { Arc::new(runtime) })
},
#[cfg(feature = "wasmtime")]
WasmExecutionMethod::Compiled => sc_executor_wasmtime::create_runtime(
blob,
sc_executor_wasmtime::Config {
heap_pages: heap_pages as u32,
allow_missing_func_imports,
cache_path: cache_path.map(ToOwned::to_owned),
semantics: sc_executor_wasmtime::Semantics {
fast_instance_reuse: true,
deterministic_stack_limit: None,
canonicalize_nans: false,
},
},
host_functions,
)
.map(|runtime| -> Arc<dyn WasmModule> { Arc::new(runtime) }),
}
}
fn decode_version(mut version: &[u8]) -> Result<RuntimeVersion, WasmError> {
let v: RuntimeVersion = sp_api::OldRuntimeVersion::decode(&mut &version[..])
.map_err(|_|
WasmError::Instantiation(
"failed to decode \"Core_version\" result using old runtime version".into(),
)
)?.into();
.map_err(|_| {
WasmError::Instantiation(
"failed to decode \"Core_version\" result using old runtime version".into(),
)
})?
.into();
let core_api_id = sp_core::hashing::blake2_64(b"Core");
if v.has_api_with(&core_api_id, |v| v >= 3) {
sp_api::RuntimeVersion::decode(&mut version)
.map_err(|_|
WasmError::Instantiation("failed to decode \"Core_version\" result".into())
)
sp_api::RuntimeVersion::decode(&mut version).map_err(|_| {
WasmError::Instantiation("failed to decode \"Core_version\" result".into())
})
} else {
Ok(v)
}
}
fn decode_runtime_apis(apis: &[u8]) -> Result<Vec<([u8; 8], u32)>, WasmError> {
use std::convert::TryFrom;
use sp_api::RUNTIME_API_INFO_SIZE;
use std::convert::TryFrom;
apis.chunks(RUNTIME_API_INFO_SIZE)
.map(|chunk| {
@@ -367,9 +364,7 @@ fn decode_runtime_apis(apis: &[u8]) -> Result<Vec<([u8; 8], u32)>, WasmError> {
// completely divide by `RUNTIME_API_INFO_SIZE`.
<[u8; RUNTIME_API_INFO_SIZE]>::try_from(chunk)
.map(sp_api::deserialize_runtime_api_info)
.map_err(|_| {
WasmError::Other("a clipped runtime api info declaration".to_owned())
})
.map_err(|_| WasmError::Other("a clipped runtime api info declaration".to_owned()))
})
.collect::<Result<Vec<_>, WasmError>>()
}
@@ -379,9 +374,7 @@ fn decode_runtime_apis(apis: &[u8]) -> Result<Vec<([u8; 8], u32)>, WasmError> {
///
/// If there are no such sections, it returns `None`. If there is an error during decoding those
/// sections, `Err` will be returned.
pub fn read_embedded_version(
blob: &RuntimeBlob,
) -> Result<Option<RuntimeVersion>, WasmError> {
pub fn read_embedded_version(blob: &RuntimeBlob) -> Result<Option<RuntimeVersion>, WasmError> {
if let Some(mut version_section) = blob.custom_section_contents("runtime_version") {
// We do not use `decode_version` here because the runtime_version section is not supposed
// to ever contain a legacy version. Apart from that `decode_version` relies on presence
@@ -389,9 +382,7 @@ pub fn read_embedded_version(
// the structure found in the `runtime_version` always contain an empty `apis` field. Therefore
// the version read will be mistakenly treated as an legacy one.
let mut decoded_version = sp_api::RuntimeVersion::decode(&mut version_section)
.map_err(|_|
WasmError::Instantiation("failed to decode version section".into())
)?;
.map_err(|_| WasmError::Instantiation("failed to decode version section".into()))?;
// Don't stop on this and check if there is a special section that encodes all runtime APIs.
if let Some(apis_section) = blob.custom_section_contents("runtime_apis") {
@@ -443,10 +434,10 @@ fn create_versioned_wasm_runtime(
// The following unwind safety assertion is OK because if the method call panics, the
// runtime will be dropped.
let runtime = AssertUnwindSafe(runtime.as_ref());
crate::native_executor::with_externalities_safe(
&mut **ext,
move || runtime.new_instance()?.call("Core_version".into(), &[])
).map_err(|_| WasmError::Instantiation("panic in call to get runtime version".into()))?
crate::native_executor::with_externalities_safe(&mut **ext, move || {
runtime.new_instance()?.call("Core_version".into(), &[])
})
.map_err(|_| WasmError::Instantiation("panic in call to get runtime version".into()))?
};
if let Ok(version_buf) = version_result {
@@ -457,23 +448,16 @@ fn create_versioned_wasm_runtime(
let mut instances = Vec::with_capacity(max_instances);
instances.resize_with(max_instances, || Mutex::new(None));
Ok(VersionedRuntime {
code_hash,
module: runtime,
version,
heap_pages,
wasm_method,
instances,
})
Ok(VersionedRuntime { code_hash, module: runtime, version, heap_pages, wasm_method, instances })
}
#[cfg(test)]
mod tests {
use super::*;
use sp_wasm_interface::HostFunctions;
use sp_api::{Core, RuntimeApiInfo};
use substrate_test_runtime::Block;
use codec::Encode;
use sp_api::{Core, RuntimeApiInfo};
use sp_wasm_interface::HostFunctions;
use substrate_test_runtime::Block;
#[test]
fn host_functions_are_equal() {
@@ -533,7 +517,8 @@ mod tests {
let wasm = sp_maybe_compressed_blob::decompress(
substrate_test_runtime::wasm_binary_unwrap(),
sp_maybe_compressed_blob::CODE_BLOB_BOMB_LIMIT,
).expect("Decompressing works");
)
.expect("Decompressing works");
let runtime_version = RuntimeVersion {
spec_name: "test_replace".into(),
@@ -545,10 +530,8 @@ mod tests {
transaction_version: 100,
};
let embedded = sp_version::embed::embed_runtime_version(
&wasm,
runtime_version.clone(),
).expect("Embedding works");
let embedded = sp_version::embed::embed_runtime_version(&wasm, runtime_version.clone())
.expect("Embedding works");
let blob = RuntimeBlob::new(&embedded).expect("Embedded blob is valid");
let read_version = read_embedded_version(&blob)