Skip to content
lib.rs 31.9 KiB
Newer Older
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.

//! This is part of the Substrate runtime.

#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]
#![cfg_attr(feature = "std",
   doc = "Substrate runtime standard library as compiled when linked with Rust's standard library.")]
#![cfg_attr(not(feature = "std"),
   doc = "Substrate's runtime standard library as compiled without Rust's standard library.")]
use sp_std::vec::Vec;
#[cfg(feature = "std")]
use sp_std::ops::Deref;

#[cfg(feature = "std")]
	crypto::Pair,
	traits::{KeystoreExt, CallInWasmExt},
	offchain::{OffchainExt, TransactionPoolExt},
	hexdisplay::HexDisplay,
	storage::{ChildStorageKey, ChildInfo},
	crypto::KeyTypeId, ed25519, sr25519, H256, LogLevel,
	offchain::{
		Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState,
	},
#[cfg(feature = "std")]
use sp_trie::{TrieConfiguration, trie_types::Layout};
use sp_runtime_interface::{runtime_interface, Pointer};

use codec::{Encode, Decode};

#[cfg(feature = "std")]
use sp_externalities::{ExternalitiesExt, Externalities};
/// Error verifying ECDSA signature
#[derive(Encode, Decode)]
pub enum EcdsaVerifyError {
/// Returns a `ChildStorageKey` if the given `storage_key` slice is a valid storage
/// key or panics otherwise.
///
/// Panicking here is aligned with what the `without_std` environment would do
/// in the case of an invalid child storage key.
#[cfg(feature = "std")]
fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey {
	match ChildStorageKey::from_slice(storage_key) {
		Some(storage_key) => storage_key,
		None => panic!("child storage key is invalid"),
	}
}

/// Interface for accessing the storage from within the runtime.
#[runtime_interface]
pub trait Storage {
	/// Returns the data for `key` in the storage or `None` if the key can not be found.
	fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
		self.storage(key).map(|s| s.to_vec())
	}

	/// All Child api uses :
	/// - A `child_storage_key` to define the anchor point for the child proof
	/// (commonly the location where the child root is stored in its parent trie).
	/// - A `child_storage_types` to identify the kind of the child type and how its
	/// `child definition` parameter is encoded.
	/// - A `child_definition_parameter` which is the additional information required
	/// to use the child trie. For instance defaults child tries requires this to
	/// contain a collision free unique id.
	///
	/// This function specifically returns the data for `key` in the child storage or `None`
	/// if the key can not be found.
	fn child_get(
		&self,
		child_storage_key: &[u8],
		child_definition: &[u8],
		child_type: u32,
		key: &[u8],
	) -> Option<Vec<u8>> {
		let storage_key = child_storage_key_or_panic(child_storage_key);
		let child_info = ChildInfo::resolve_child_info(child_type, child_definition)
			.expect("Invalid child definition");
		self.child_storage(storage_key, child_info, key).map(|s| s.to_vec())
	}

	/// Get `key` from storage, placing the value into `value_out` and return the number of
	/// bytes that the entry in storage has beyond the offset or `None` if the storage entry
	/// doesn't exist at all.
	/// If `value_out` length is smaller than the returned length, only `value_out` length bytes
	/// are copied into `value_out`.
	fn read(&self, key: &[u8], value_out: &mut [u8], value_offset: u32) -> Option<u32> {
		self.storage(key).map(|value| {
			let value_offset = value_offset as usize;
			let data = &value[value_offset.min(value.len())..];
			let written = std::cmp::min(data.len(), value_out.len());
			value_out[..written].copy_from_slice(&data[..written]);
			value.len() as u32
		})
	}

	/// Get `key` from child storage, placing the value into `value_out` and return the number
	/// of bytes that the entry in storage has beyond the offset or `None` if the storage entry
	/// doesn't exist at all.
	/// If `value_out` length is smaller than the returned length, only `value_out` length bytes
	/// are copied into `value_out`.
	///
	/// See `child_get` for common child api parameters.
	fn child_read(
		&self,
		child_storage_key: &[u8],
		child_definition: &[u8],
		child_type: u32,
		key: &[u8],
		value_out: &mut [u8],
		value_offset: u32,
	) -> Option<u32> {
		let storage_key = child_storage_key_or_panic(child_storage_key);
		let child_info = ChildInfo::resolve_child_info(child_type, child_definition)
			.expect("Invalid child definition");
		self.child_storage(storage_key, child_info, key)
			.map(|value| {
				let value_offset = value_offset as usize;
				let data = &value[value_offset.min(value.len())..];
				let written = std::cmp::min(data.len(), value_out.len());
				value_out[..written].copy_from_slice(&data[..written]);
				value.len() as u32
			})
	}

	/// Set `key` to `value` in the storage.
	fn set(&mut self, key: &[u8], value: &[u8]) {
		self.set_storage(key.to_vec(), value.to_vec());
	}

	/// Set `key` to `value` in the child storage denoted by `child_storage_key`.
	///
	/// See `child_get` for common child api parameters.
	fn child_set(
		&mut self,
		child_storage_key: &[u8],
		child_definition: &[u8],
		child_type: u32,
		key: &[u8],
		value: &[u8],
	) {
		let storage_key = child_storage_key_or_panic(child_storage_key);
		let child_info = ChildInfo::resolve_child_info(child_type, child_definition)
			.expect("Invalid child definition");
		self.set_child_storage(storage_key, child_info, key.to_vec(), value.to_vec());
	}

	/// Clear the storage of the given `key` and its value.
	fn clear(&mut self, key: &[u8]) {
		self.clear_storage(key)
	}

	/// Clear the given child storage of the given `key` and its value.
	///
	/// See `child_get` for common child api parameters.
	fn child_clear(
		&mut self,
		child_storage_key: &[u8],
		child_definition: &[u8],
		child_type: u32,
		key: &[u8],
	) {
		let storage_key = child_storage_key_or_panic(child_storage_key);
		let child_info = ChildInfo::resolve_child_info(child_type, child_definition)
			.expect("Invalid child definition");
		self.clear_child_storage(storage_key, child_info, key);
Loading full blame...