diff --git a/client/executor/src/host_interface.rs b/client/executor/src/host_interface.rs
deleted file mode 100644
index 0499cad5663ce..0000000000000
--- a/client/executor/src/host_interface.rs
+++ /dev/null
@@ -1,1075 +0,0 @@
-// 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 .
-
-//! Definition and implementation of the old and deprecated Substrate runtime interface for the host.
-
-use codec::Encode;
-use std::{convert::TryFrom, str};
-use primitives::{
- blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Blake2Hasher, Pair,
- crypto::KeyTypeId, offchain,
-};
-use trie::{TrieConfiguration, trie_types::Layout};
-use wasm_interface::{
- Pointer, WordSize, WritePrimitive, ReadPrimitive, FunctionContext, Result as WResult,
-};
-
-#[cfg(feature="wasm-extern-trace")]
-macro_rules! debug_trace {
- ( $( $x:tt )* ) => ( trace!( $( $x )* ) )
-}
-
-#[cfg(not(feature="wasm-extern-trace"))]
-macro_rules! debug_trace {
- ( $( $x:tt )* ) => ()
-}
-
-/// The old and deprecated Substrate externals. These are still required for backwards compatibility
-/// reasons.
-pub struct SubstrateExternals;
-
-enum RecoverResult {
- Invalid(u32),
- Valid(secp256k1::PublicKey),
-}
-
-fn secp256k1_recover(
- context: &mut dyn FunctionContext,
- msg_data: Pointer,
- sig_data: Pointer,
-) -> WResult {
- let mut sig = [0u8; 65];
- context.read_memory_into(sig_data, &mut sig[..])
- .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?;
- let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) {
- Ok(rs) => rs,
- _ => return Ok(RecoverResult::Invalid(1)),
- };
-
- let recovery_id = if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8;
- let v = match secp256k1::RecoveryId::parse(recovery_id) {
- Ok(v) => v,
- _ => return Ok(RecoverResult::Invalid(2)),
- };
-
- let mut msg = [0u8; 32];
- context.read_memory_into(msg_data, &mut msg[..])
- .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?;
-
- Ok(match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) {
- Ok(pubkey) => RecoverResult::Valid(pubkey),
- Err(_) => RecoverResult::Invalid(3),
- })
-}
-
-impl_wasm_host_interface! {
- impl SubstrateExternals where context {
- ext_malloc(size: WordSize) -> Pointer {
- let r = context.allocate_memory(size)?;
- debug_trace!(target: "sr-io", "malloc {} bytes at {:?}", size, r);
- Ok(r)
- }
-
- ext_free(addr: Pointer) {
- context.deallocate_memory(addr)?;
- debug_trace!(target: "sr-io", "free {:?}", addr);
- Ok(())
- }
-
- ext_sandbox_instantiate(
- dispatch_thunk_idx: u32,
- wasm_ptr: Pointer,
- wasm_len: WordSize,
- imports_ptr: Pointer,
- imports_len: WordSize,
- state: u32,
- ) -> u32 {
- let wasm = context.read_memory(wasm_ptr, wasm_len)
- .map_err(|_| "OOB while ext_sandbox_instantiate: wasm")?;
- let raw_env_def = context.read_memory(imports_ptr, imports_len)
- .map_err(|_| "OOB while ext_sandbox_instantiate: imports")?;
-
- context.sandbox().instance_new(dispatch_thunk_idx, &wasm, &raw_env_def, state)
- }
-
- ext_sandbox_instance_teardown(instance_idx: u32) {
- context.sandbox().instance_teardown(instance_idx)
- }
-
- ext_sandbox_invoke(
- instance_idx: u32,
- export_ptr: Pointer,
- export_len: WordSize,
- args_ptr: Pointer,
- args_len: WordSize,
- return_val_ptr: Pointer,
- return_val_len: WordSize,
- state: u32,
- ) -> u32 {
- let export = context.read_memory(export_ptr, export_len)
- .map_err(|_| "OOB while ext_sandbox_invoke: export")
- .and_then(|b|
- String::from_utf8(b)
- .map_err(|_| "Export name should be a valid utf-8 sequence")
- )?;
-
- // Deserialize arguments and convert them into wasmi types.
- let serialized_args = context.read_memory(args_ptr, args_len)
- .map_err(|_| "OOB while ext_sandbox_invoke: args")?;
-
- context.sandbox().invoke(
- instance_idx,
- &export,
- &serialized_args,
- return_val_ptr,
- return_val_len,
- state,
- )
- }
-
- ext_sandbox_memory_new(initial: WordSize, maximum: WordSize) -> u32 {
- context.sandbox().memory_new(initial, maximum)
- }
-
- ext_sandbox_memory_get(
- memory_idx: u32,
- offset: WordSize,
- buf_ptr: Pointer,
- buf_len: WordSize,
- ) -> u32 {
- context.sandbox().memory_get(memory_idx, offset, buf_ptr, buf_len)
- }
-
- ext_sandbox_memory_set(
- memory_idx: u32,
- offset: WordSize,
- val_ptr: Pointer,
- val_len: WordSize,
- ) -> u32 {
- context.sandbox().memory_set(memory_idx, offset, val_ptr, val_len)
- }
-
- ext_sandbox_memory_teardown(memory_idx: u32) {
- context.sandbox().memory_teardown(memory_idx)
- }
-
- ext_print_utf8(utf8_data: Pointer, utf8_len: WordSize) {
- if let Ok(utf8) = context.read_memory(utf8_data, utf8_len) {
- runtime_io::misc::print_utf8(&utf8);
- }
- Ok(())
- }
-
- ext_print_hex(data: Pointer, len: WordSize) {
- if let Ok(hex) = context.read_memory(data, len) {
- runtime_io::misc::print_hex(&hex);
- }
- Ok(())
- }
-
- ext_print_num(number: u64) {
- runtime_io::misc::print_num(number);
- Ok(())
- }
-
- ext_log(
- level: u32,
- target_data: Pointer,
- target_len: WordSize,
- message_data: Pointer,
- message_len: WordSize,
- ) {
- let target = context.read_memory(target_data, target_len)
- .map_err(|_| "Invalid attempt to determine target in ext_log")?;
- let message = context.read_memory(message_data, message_len)
- .map_err(|_| "Invalid attempt to determine message in ext_log")?;
-
- let target_str = std::str::from_utf8(&target)
- .map_err(|_| "Target invalid utf8 in ext_log")?;
-
- runtime_io::logging::log(level.into(), &target_str, &message);
- Ok(())
- }
-
- ext_set_storage(
- key_data: Pointer,
- key_len: WordSize,
- value_data: Pointer,
- value_len: WordSize,
- ) {
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?;
- let value = context.read_memory(value_data, value_len)
- .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?;
- Ok(runtime_io::storage::set(&key, &value))
- }
-
- ext_set_child_storage(
- storage_key_data: Pointer,
- storage_key_len: WordSize,
- key_data: Pointer,
- key_len: WordSize,
- value_data: Pointer,
- value_len: WordSize,
- ) {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_set_child_storage")?;
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_set_child_storage")?;
- let value = context.read_memory(value_data, value_len)
- .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?;
-
- Ok(runtime_io::storage::child_set(&storage_key, &key, &value))
- }
-
- ext_clear_child_storage(
- storage_key_data: Pointer,
- storage_key_len: WordSize,
- key_data: Pointer,
- key_len: WordSize,
- ) {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_storage")?;
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?;
-
- Ok(runtime_io::storage::child_clear(&storage_key, &key))
- }
-
- ext_clear_storage(key_data: Pointer, key_len: WordSize) {
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?;
- Ok(runtime_io::storage::clear(&key))
- }
-
- ext_exists_storage(key_data: Pointer, key_len: WordSize) -> u32 {
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?;
- Ok(if runtime_io::storage::exists(&key) { 1 } else { 0 })
- }
-
- ext_exists_child_storage(
- storage_key_data: Pointer,
- storage_key_len: WordSize,
- key_data: Pointer,
- key_len: WordSize,
- ) -> u32 {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_exists_child_storage")?;
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?;
-
- Ok(if runtime_io::storage::child_exists(&storage_key, &key) { 1 } else { 0 })
- }
-
- ext_clear_prefix(prefix_data: Pointer, prefix_len: WordSize) {
- let prefix = context.read_memory(prefix_data, prefix_len)
- .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?;
- Ok(runtime_io::storage::clear_prefix(&prefix))
- }
-
- ext_clear_child_prefix(
- storage_key_data: Pointer,
- storage_key_len: WordSize,
- prefix_data: Pointer,
- prefix_len: WordSize,
- ) {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?;
- let prefix = context.read_memory(prefix_data, prefix_len)
- .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?;
- Ok(runtime_io::storage::child_clear_prefix(&storage_key, &prefix))
- }
-
- ext_kill_child_storage(storage_key_data: Pointer, storage_key_len: WordSize) {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?;
- Ok(runtime_io::storage::child_storage_kill(&storage_key))
- }
-
- ext_get_allocated_storage(
- key_data: Pointer,
- key_len: WordSize,
- written_out: Pointer,
- ) -> Pointer {
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?;
-
- if let Some(value) = runtime_io::storage::get(&key) {
- let offset = context.allocate_memory(value.len() as u32)?;
- context.write_memory(offset, &value)
- .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_storage")?;
- context.write_primitive(written_out, value.len() as u32)
- .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_storage")?;
- Ok(offset)
- } else {
- context.write_primitive(written_out, u32::max_value())
- .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_storage")?;
- Ok(Pointer::null())
- }
- }
-
- ext_get_allocated_child_storage(
- storage_key_data: Pointer,
- storage_key_len: WordSize,
- key_data: Pointer,
- key_len: WordSize,
- written_out: Pointer,
- ) -> Pointer {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_get_allocated_child_storage")?;
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?;
-
- if let Some(value) = runtime_io::storage::child_get(&storage_key, &key) {
- let offset = context.allocate_memory(value.len() as u32)?;
- context.write_memory(offset, &value)
- .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_child_storage")?;
- context.write_primitive(written_out, value.len() as u32)
- .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_child_storage")?;
- Ok(offset)
- } else {
- context.write_primitive(written_out, u32::max_value())
- .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_child_storage")?;
- Ok(Pointer::null())
- }
- }
-
- ext_get_storage_into(
- key_data: Pointer,
- key_len: WordSize,
- value_data: Pointer,
- value_len: WordSize,
- value_offset: WordSize,
- ) -> WordSize {
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?;
-
- if let Some(value) = runtime_io::storage::get(&key) {
- let data = &value[value.len().min(value_offset as usize)..];
- let written = std::cmp::min(value_len as usize, data.len());
- context.write_memory(value_data, &data[..written])
- .map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?;
- Ok(value.len() as u32)
- } else {
- Ok(u32::max_value())
- }
- }
-
- ext_get_child_storage_into(
- storage_key_data: Pointer,
- storage_key_len: WordSize,
- key_data: Pointer,
- key_len: WordSize,
- value_data: Pointer,
- value_len: WordSize,
- value_offset: WordSize,
- ) -> WordSize {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_get_child_storage_into")?;
- let key = context.read_memory(key_data, key_len)
- .map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?;
-
- if let Some(value) = runtime_io::storage::child_get(&storage_key, &key) {
- let data = &value[value.len().min(value_offset as usize)..];
- let written = std::cmp::min(value_len as usize, data.len());
- context.write_memory(value_data, &data[..written])
- .map_err(|_| "Invalid attempt to get value in ext_get_child_storage_into")?;
- Ok(value.len() as u32)
- } else {
- Ok(u32::max_value())
- }
- }
-
- ext_storage_root(result: Pointer) {
- context.write_memory(result, runtime_io::storage::root().as_ref())
- .map_err(|_| "Invalid attempt to set memory in ext_storage_root".into())
- }
-
- ext_child_storage_root(
- storage_key_data: Pointer,
- storage_key_len: WordSize,
- written_out: Pointer,
- ) -> Pointer {
- let storage_key = context.read_memory(storage_key_data, storage_key_len)
- .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?;
- let value = runtime_io::storage::child_root(&storage_key);
-
- let offset = context.allocate_memory(value.len() as u32)?;
- context.write_memory(offset, &value)
- .map_err(|_| "Invalid attempt to set memory in ext_child_storage_root")?;
- context.write_primitive(written_out, value.len() as u32)
- .map_err(|_| "Invalid attempt to write written_out in ext_child_storage_root")?;
- Ok(offset)
- }
-
- ext_storage_changes_root(
- parent_hash_data: Pointer,
- _len: WordSize,
- result: Pointer,
- ) -> u32 {
- let mut parent_hash = [0u8; 32];
- context.read_memory_into(parent_hash_data, &mut parent_hash[..])
- .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?;
-
- if let Some(r) = runtime_io::storage::changes_root(parent_hash) {
- context.write_memory(result, &r[..])
- .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?;
- Ok(1)
- } else {
- Ok(0)
- }
- }
-
- ext_blake2_256_enumerated_trie_root(
- values_data: Pointer,
- lens_data: Pointer,
- lens_len: WordSize,
- result: Pointer,
- ) {
- let values = (0..lens_len)
- .map(|i| context.read_primitive(lens_data.offset(i).ok_or("Pointer overflow")?))
- .collect::, _>>()?
- .into_iter()
- .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) })
- .map(|(offset, len)|
- context.read_memory(values_data.offset(offset).ok_or("Pointer overflow")?, len)
- .map_err(|_|
- "Invalid attempt to get memory in ext_blake2_256_enumerated_trie_root"
- )
- )
- .collect::, _>>()?;
- let r = Layout::::ordered_trie_root(values.into_iter());
- context.write_memory(result, &r[..])
- .map_err(|_| "Invalid attempt to set memory in ext_blake2_256_enumerated_trie_root")?;
- Ok(())
- }
-
- ext_chain_id() -> u64 {
- Ok(runtime_io::misc::chain_id())
- }
-
- ext_twox_64(data: Pointer, len: WordSize, out: Pointer) {
- let result: [u8; 8] = if len == 0 {
- let hashed = twox_64(&[0u8; 0]);
- hashed
- } else {
- let key = context.read_memory(data, len)
- .map_err(|_| "Invalid attempt to get key in ext_twox_64")?;
- let hashed_key = twox_64(&key);
- hashed_key
- };
-
- context.write_memory(out, &result)
- .map_err(|_| "Invalid attempt to set result in ext_twox_64")?;
- Ok(())
- }
-
- ext_twox_128(data: Pointer, len: WordSize, out: Pointer) {
- let result: [u8; 16] = if len == 0 {
- let hashed = twox_128(&[0u8; 0]);
- hashed
- } else {
- let key = context.read_memory(data, len)
- .map_err(|_| "Invalid attempt to get key in ext_twox_128")?;
- let hashed_key = twox_128(&key);
- hashed_key
- };
-
- context.write_memory(out, &result)
- .map_err(|_| "Invalid attempt to set result in ext_twox_128")?;
- Ok(())
- }
-
- ext_twox_256(data: Pointer, len: WordSize, out: Pointer) {
- let result: [u8; 32] = if len == 0 {
- twox_256(&[0u8; 0])
- } else {
- let mem = context.read_memory(data, len)
- .map_err(|_| "Invalid attempt to get data in ext_twox_256")?;
- twox_256(&mem)
- };
- context.write_memory(out, &result)
- .map_err(|_| "Invalid attempt to set result in ext_twox_256")?;
- Ok(())
- }
-
- ext_blake2_128(data: Pointer, len: WordSize, out: Pointer) {
- let result: [u8; 16] = if len == 0 {
- let hashed = blake2_128(&[0u8; 0]);
- hashed
- } else {
- let key = context.read_memory(data, len)
- .map_err(|_| "Invalid attempt to get key in ext_blake2_128")?;
- let hashed_key = blake2_128(&key);
- hashed_key
- };
-
- context.write_memory(out, &result)
- .map_err(|_| "Invalid attempt to set result in ext_blake2_128")?;
- Ok(())
- }
-
- ext_blake2_256(data: Pointer, len: WordSize, out: Pointer) {
- let result: [u8; 32] = if len == 0 {
- blake2_256(&[0u8; 0])
- } else {
- let mem = context.read_memory(data, len)
- .map_err(|_| "Invalid attempt to get data in ext_blake2_256")?;
- blake2_256(&mem)
- };
- context.write_memory(out, &result)
- .map_err(|_| "Invalid attempt to set result in ext_blake2_256")?;
- Ok(())
- }
-
- ext_keccak_256(data: Pointer, len: WordSize, out: Pointer) {
- let result: [u8; 32] = if len == 0 {
- tiny_keccak::keccak256(&[0u8; 0])
- } else {
- let mem = context.read_memory(data, len)
- .map_err(|_| "Invalid attempt to get data in ext_keccak_256")?;
- tiny_keccak::keccak256(&mem)
- };
- context.write_memory(out, &result)
- .map_err(|_| "Invalid attempt to set result in ext_keccak_256")?;
- Ok(())
- }
-
- ext_ed25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer {
- let mut id = [0u8; 4];
- context.read_memory_into(id_data, &mut id[..])
- .map_err(|_| "Invalid attempt to get id in ext_ed25519_public_keys")?;
- let key_type = KeyTypeId(id);
-
- let keys = runtime_io::crypto::ed25519_public_keys(key_type).encode();
-
- let len = keys.len() as u32;
- let offset = context.allocate_memory(len)?;
-
- context.write_memory(offset, keys.as_ref())
- .map_err(|_| "Invalid attempt to set memory in ext_ed25519_public_keys")?;
- context.write_primitive(result_len, len)
- .map_err(|_| "Invalid attempt to write result_len in ext_ed25519_public_keys")?;
-
- Ok(offset)
- }
-
- ext_ed25519_verify(
- msg_data: Pointer,
- msg_len: WordSize,
- sig_data: Pointer,
- pubkey_data: Pointer,
- ) -> u32 {
- let mut sig = [0u8; 64];
- context.read_memory_into(sig_data, &mut sig[..])
- .map_err(|_| "Invalid attempt to get signature in ext_ed25519_verify")?;
- let mut pubkey = [0u8; 32];
- context.read_memory_into(pubkey_data, &mut pubkey[..])
- .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_verify")?;
- let msg = context.read_memory(msg_data, msg_len)
- .map_err(|_| "Invalid attempt to get message in ext_ed25519_verify")?;
-
- Ok(if ed25519::Pair::verify_weak(&sig, &msg, &pubkey) {
- 0
- } else {
- 1
- })
- }
-
- ext_ed25519_generate(
- id_data: Pointer,
- seed: Pointer,
- seed_len: WordSize,
- out: Pointer,
- ) {
- let mut id = [0u8; 4];
- context.read_memory_into(id_data, &mut id[..])
- .map_err(|_| "Invalid attempt to get id in ext_ed25519_generate")?;
- let key_type = KeyTypeId(id);
-
- let seed = if seed_len == 0 {
- None
- } else {
- Some(
- context.read_memory(seed, seed_len)
- .map_err(|_| "Invalid attempt to get seed in ext_ed25519_generate")?
- )
- };
-
- let pubkey = runtime_io::crypto::ed25519_generate(key_type, seed);
-
- context.write_memory(out, pubkey.as_ref())
- .map_err(|_| "Invalid attempt to set out in ext_ed25519_generate".into())
- }
-
- ext_ed25519_sign(
- id_data: Pointer,
- pubkey_data: Pointer,
- msg_data: Pointer,
- msg_len: WordSize,
- out: Pointer,
- ) -> u32 {
- let mut id = [0u8; 4];
- context.read_memory_into(id_data, &mut id[..])
- .map_err(|_| "Invalid attempt to get id in ext_ed25519_sign")?;
- let key_type = KeyTypeId(id);
-
- let mut pubkey = [0u8; 32];
- context.read_memory_into(pubkey_data, &mut pubkey[..])
- .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_sign")?;
-
- let msg = context.read_memory(msg_data, msg_len)
- .map_err(|_| "Invalid attempt to get message in ext_ed25519_sign")?;
-
- let pub_key = ed25519::Public::try_from(pubkey.as_ref())
- .map_err(|_| "Invalid `ed25519` public key")?;
-
- let signature = runtime_io::crypto::ed25519_sign(key_type, &pub_key, &msg);
-
- match signature {
- Some(signature) => {
- context.write_memory(out, signature.as_ref())
- .map_err(|_| "Invalid attempt to set out in ext_ed25519_sign")?;
- Ok(0)
- },
- None => Ok(1),
- }
- }
-
- ext_sr25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer {
- let mut id = [0u8; 4];
- context.read_memory_into(id_data, &mut id[..])
- .map_err(|_| "Invalid attempt to get id in ext_sr25519_public_keys")?;
- let key_type = KeyTypeId(id);
-
- let keys = runtime_io::crypto::sr25519_public_keys(key_type).encode();
-
- let len = keys.len() as u32;
- let offset = context.allocate_memory(len)?;
-
- context.write_memory(offset, keys.as_ref())
- .map_err(|_| "Invalid attempt to set memory in ext_sr25519_public_keys")?;
- context.write_primitive(result_len, len)
- .map_err(|_| "Invalid attempt to write result_len in ext_sr25519_public_keys")?;
-
- Ok(offset)
- }
-
- ext_sr25519_verify(
- msg_data: Pointer,
- msg_len: WordSize,
- sig_data: Pointer,
- pubkey_data: Pointer,
- ) -> u32 {
- let mut sig = [0u8; 64];
- context.read_memory_into(sig_data, &mut sig[..])
- .map_err(|_| "Invalid attempt to get signature in ext_sr25519_verify")?;
- let mut pubkey = [0u8; 32];
- context.read_memory_into(pubkey_data, &mut pubkey[..])
- .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_verify")?;
- let msg = context.read_memory(msg_data, msg_len)
- .map_err(|_| "Invalid attempt to get message in ext_sr25519_verify")?;
-
- Ok(if sr25519::Pair::verify_weak(&sig, &msg, &pubkey) {
- 0
- } else {
- 1
- })
- }
-
- ext_sr25519_generate(
- id_data: Pointer,
- seed: Pointer,
- seed_len: WordSize,
- out: Pointer,
- ) {
- let mut id = [0u8; 4];
- context.read_memory_into(id_data, &mut id[..])
- .map_err(|_| "Invalid attempt to get id in ext_sr25519_generate")?;
- let key_type = KeyTypeId(id);
- let seed = if seed_len == 0 {
- None
- } else {
- Some(
- context.read_memory(seed, seed_len)
- .map_err(|_| "Invalid attempt to get seed in ext_sr25519_generate")?
- )
- };
-
- let pubkey = runtime_io::crypto::sr25519_generate(key_type, seed);
-
- context.write_memory(out, pubkey.as_ref())
- .map_err(|_| "Invalid attempt to set out in ext_sr25519_generate".into())
- }
-
- ext_sr25519_sign(
- id_data: Pointer,
- pubkey_data: Pointer,
- msg_data: Pointer,
- msg_len: WordSize,
- out: Pointer,
- ) -> u32 {
- let mut id = [0u8; 4];
- context.read_memory_into(id_data, &mut id[..])
- .map_err(|_| "Invalid attempt to get id in ext_sr25519_sign")?;
- let key_type = KeyTypeId(id);
-
- let mut pubkey = [0u8; 32];
- context.read_memory_into(pubkey_data, &mut pubkey[..])
- .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_sign")?;
-
- let msg = context.read_memory(msg_data, msg_len)
- .map_err(|_| "Invalid attempt to get message in ext_sr25519_sign")?;
-
- let pub_key = sr25519::Public::try_from(pubkey.as_ref())
- .map_err(|_| "Invalid `sr25519` public key")?;
-
- let signature = runtime_io::crypto::sr25519_sign(key_type, &pub_key, &msg);
-
- match signature {
- Some(signature) => {
- context.write_memory(out, signature.as_ref())
- .map_err(|_| "Invalid attempt to set out in ext_sr25519_sign")?;
- Ok(0)
- },
- None => Ok(1),
- }
- }
-
- ext_secp256k1_ecdsa_recover(
- msg_data: Pointer,
- sig_data: Pointer,
- pubkey_data: Pointer,
- ) -> u32 {
- match secp256k1_recover(context, msg_data, sig_data)? {
- RecoverResult::Invalid(c) => Ok(c),
- RecoverResult::Valid(pubkey) => {
- context.write_memory(pubkey_data, &pubkey.serialize()[1..65])
- .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?;
- Ok(0)
- }
- }
- }
-
- ext_secp256k1_ecdsa_recover_compressed(
- msg_data: Pointer,
- sig_data: Pointer,
- pubkey_data: Pointer,
- ) -> u32 {
- match secp256k1_recover(context, msg_data, sig_data)? {
- RecoverResult::Invalid(c) => Ok(c),
- RecoverResult::Valid(pubkey) => {
- context.write_memory(pubkey_data, &pubkey.serialize_compressed()[..])
- .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?;
- Ok(0)
- }
- }
- }
-
- ext_is_validator() -> u32 {
- if runtime_io::offchain::is_validator() { Ok(1) } else { Ok(0) }
- }
-
- ext_submit_transaction(msg_data: Pointer, len: WordSize) -> u32 {
- let extrinsic = context.read_memory(msg_data, len)
- .map_err(|_| "OOB while ext_submit_transaction: wasm")?;
-
- let res = runtime_io::offchain::submit_transaction(extrinsic);
-
- Ok(if res.is_ok() { 0 } else { 1 })
- }
-
- ext_network_state(written_out: Pointer) -> Pointer {
- let res = runtime_io::offchain::network_state();
-
- let encoded = res.encode();
- let len = encoded.len() as u32;
- let offset = context.allocate_memory(len)?;
- context.write_memory(offset, &encoded)
- .map_err(|_| "Invalid attempt to set memory in ext_network_state")?;
-
- context.write_primitive(written_out, len)
- .map_err(|_| "Invalid attempt to write written_out in ext_network_state")?;
-
- Ok(offset)
- }
-
- ext_timestamp() -> u64 {
- Ok(runtime_io::offchain::timestamp().unix_millis())
- }
-
- ext_sleep_until(deadline: u64) {
- runtime_io::offchain::sleep_until(offchain::Timestamp::from_unix_millis(deadline));
- Ok(())
- }
-
- ext_random_seed(seed_data: Pointer) {
- // NOTE the runtime as assumptions about seed size.
- let seed = runtime_io::offchain::random_seed();
-
- context.write_memory(seed_data, &seed)
- .map_err(|_| "Invalid attempt to set value in ext_random_seed")?;
- Ok(())
- }
-
- ext_local_storage_set(
- kind: u32,
- key: Pointer,
- key_len: WordSize,
- value: Pointer,
- value_len: WordSize,
- ) {
- let kind = offchain::StorageKind::try_from(kind)
- .map_err(|_| "storage kind OOB while ext_local_storage_set: wasm")?;
- let key = context.read_memory(key, key_len)
- .map_err(|_| "OOB while ext_local_storage_set: wasm")?;
- let value = context.read_memory(value, value_len)
- .map_err(|_| "OOB while ext_local_storage_set: wasm")?;
-
- runtime_io::offchain::local_storage_set(kind, &key, &value);
-
- Ok(())
- }
-
- ext_local_storage_get(
- kind: u32,
- key: Pointer,
- key_len: WordSize,
- value_len: Pointer,
- ) -> Pointer {
- let kind = offchain::StorageKind::try_from(kind)
- .map_err(|_| "storage kind OOB while ext_local_storage_get: wasm")?;
- let key = context.read_memory(key, key_len)
- .map_err(|_| "OOB while ext_local_storage_get: wasm")?;
-
- let maybe_value = runtime_io::offchain::local_storage_get(kind, &key);
-
- let (offset, len) = if let Some(value) = maybe_value {
- let offset = context.allocate_memory(value.len() as u32)?;
- context.write_memory(offset, &value)
- .map_err(|_| "Invalid attempt to set memory in ext_local_storage_get")?;
- (offset, value.len() as u32)
- } else {
- (Pointer::null(), u32::max_value())
- };
-
- context.write_primitive(value_len, len)
- .map_err(|_| "Invalid attempt to write value_len in ext_local_storage_get")?;
-
- Ok(offset)
- }
-
- ext_local_storage_compare_and_set(
- kind: u32,
- key: Pointer,
- key_len: WordSize,
- old_value: Pointer,
- old_value_len: WordSize,
- new_value: Pointer,
- new_value_len: WordSize,
- ) -> u32 {
- let kind = offchain::StorageKind::try_from(kind)
- .map_err(|_| "storage kind OOB while ext_local_storage_compare_and_set: wasm")?;
- let key = context.read_memory(key, key_len)
- .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?;
- let new_value = context.read_memory(new_value, new_value_len)
- .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?;
-
- let old_value = if old_value_len == u32::max_value() {
- None
- } else {
- Some(
- context.read_memory(old_value, old_value_len)
- .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?
- )
- };
-
- let res = runtime_io::offchain::local_storage_compare_and_set(
- kind,
- &key,
- old_value,
- &new_value,
- );
-
- Ok(if res { 0 } else { 1 })
- }
-
- ext_http_request_start(
- method: Pointer,
- method_len: WordSize,
- url: Pointer,
- url_len: WordSize,
- meta: Pointer,
- meta_len: WordSize,
- ) -> u32 {
- let method = context.read_memory(method, method_len)
- .map_err(|_| "OOB while ext_http_request_start: wasm")?;
- let url = context.read_memory(url, url_len)
- .map_err(|_| "OOB while ext_http_request_start: wasm")?;
- let meta = context.read_memory(meta, meta_len)
- .map_err(|_| "OOB while ext_http_request_start: wasm")?;
-
- let method_str = str::from_utf8(&method)
- .map_err(|_| "invalid str while ext_http_request_start: wasm")?;
- let url_str = str::from_utf8(&url)
- .map_err(|_| "invalid str while ext_http_request_start: wasm")?;
-
- let id = runtime_io::offchain::http_request_start(method_str, url_str, &meta);
-
- if let Ok(id) = id {
- Ok(id.into())
- } else {
- Ok(u32::max_value())
- }
- }
-
- ext_http_request_add_header(
- request_id: u32,
- name: Pointer,
- name_len: WordSize,
- value: Pointer,
- value_len: WordSize,
- ) -> u32 {
- let name = context.read_memory(name, name_len)
- .map_err(|_| "OOB while ext_http_request_add_header: wasm")?;
- let value = context.read_memory(value, value_len)
- .map_err(|_| "OOB while ext_http_request_add_header: wasm")?;
-
- let name_str = str::from_utf8(&name)
- .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?;
- let value_str = str::from_utf8(&value)
- .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?;
-
- let res = runtime_io::offchain::http_request_add_header(
- offchain::HttpRequestId(request_id as u16),
- name_str,
- value_str,
- );
-
- Ok(if res.is_ok() { 0 } else { 1 })
- }
-
- ext_http_request_write_body(
- request_id: u32,
- chunk: Pointer,
- chunk_len: WordSize,
- deadline: u64,
- ) -> u32 {
- let chunk = context.read_memory(chunk, chunk_len)
- .map_err(|_| "OOB while ext_http_request_write_body: wasm")?;
-
- let res = runtime_io::offchain::http_request_write_body(
- offchain::HttpRequestId(request_id as u16),
- &chunk,
- deadline_to_timestamp(deadline),
- );
-
- Ok(match res {
- Ok(()) => 0,
- Err(e) => e.into(),
- })
- }
-
- ext_http_response_wait(
- ids: Pointer,
- ids_len: WordSize,
- statuses: Pointer,
- deadline: u64,
- ) {
- let ids = (0..ids_len)
- .map(|i|
- context.read_primitive(ids.offset(i).ok_or("Point overflow")?)
- .map(|id: u32| offchain::HttpRequestId(id as u16))
- .map_err(|_| "OOB while ext_http_response_wait: wasm")
- )
- .collect::, _>>()?;
-
- let res = runtime_io::offchain::http_response_wait(&ids, deadline_to_timestamp(deadline))
- .into_iter()
- .map(|status| u32::from(status))
- .enumerate()
- // make sure to take up to `ids_len` to avoid exceeding the mem.
- .take(ids_len as usize);
-
- for (i, status) in res {
- context.write_primitive(statuses.offset(i as u32).ok_or("Point overflow")?, status)
- .map_err(|_| "Invalid attempt to set memory in ext_http_response_wait")?;
- }
-
- Ok(())
- }
-
- ext_http_response_headers(
- request_id: u32,
- written_out: Pointer,
- ) -> Pointer {
- use codec::Encode;
-
- let headers = runtime_io::offchain::http_response_headers(
- offchain::HttpRequestId(request_id as u16),
- );
-
- let encoded = headers.encode();
- let len = encoded.len() as u32;
- let offset = context.allocate_memory(len)?;
-
- context.write_memory(offset, &encoded)
- .map_err(|_| "Invalid attempt to set memory in ext_http_response_headers")?;
- context.write_primitive(written_out, len)
- .map_err(|_| "Invalid attempt to write written_out in ext_http_response_headers")?;
-
- Ok(offset)
- }
-
- ext_http_response_read_body(
- request_id: u32,
- buffer: Pointer,
- buffer_len: WordSize,
- deadline: u64,
- ) -> WordSize {
- let mut internal_buffer = Vec::with_capacity(buffer_len as usize);
- internal_buffer.resize(buffer_len as usize, 0);
-
- let res = runtime_io::offchain::http_response_read_body(
- offchain::HttpRequestId(request_id as u16),
- &mut internal_buffer,
- deadline_to_timestamp(deadline),
- );
-
- Ok(match res {
- Ok(read) => {
- context.write_memory(buffer, &internal_buffer[..read as usize])
- .map_err(|_| "Invalid attempt to set memory in ext_http_response_read_body")?;
-
- read as u32
- },
- Err(err) => {
- u32::max_value() - u32::from(err) + 1
- }
- })
- }
- }
-}
-
-fn deadline_to_timestamp(deadline: u64) -> Option {
- if deadline == 0 {
- None
- } else {
- Some(offchain::Timestamp::from_unix_millis(deadline))
- }
-}
-