diff --git a/substrate/core/cli/src/lib.rs b/substrate/core/cli/src/lib.rs index 275399bdf3..d0cef45585 100644 --- a/substrate/core/cli/src/lib.rs +++ b/substrate/core/cli/src/lib.rs @@ -745,10 +745,10 @@ fn init_logger(pattern: &str) { builder.filter(None, log::LevelFilter::Info); if let Ok(lvl) = std::env::var("RUST_LOG") { - builder.parse(&lvl); + builder.parse_filters(&lvl); } - builder.parse(pattern); + builder.parse_filters(pattern); let isatty = atty::is(atty::Stream::Stderr); let enable_color = isatty; diff --git a/substrate/core/executor/wasm/src/lib.rs b/substrate/core/executor/wasm/src/lib.rs index 294c21d146..842749dd5b 100644 --- a/substrate/core/executor/wasm/src/lib.rs +++ b/substrate/core/executor/wasm/src/lib.rs @@ -92,7 +92,7 @@ impl_stubs!( [sr25519_verify(&sig, &msg[..], &pubkey) as u8].to_vec() }, test_enumerated_trie_root => |_| { - enumerated_trie_root::(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() + enumerated_trie_root::(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).as_ref().to_vec() }, test_sandbox => |code: &[u8]| { let ok = execute_sandboxed(code, &[]).is_ok(); diff --git a/substrate/core/peerset/src/lib.rs b/substrate/core/peerset/src/lib.rs index b801f47b58..570dcf5f86 100644 --- a/substrate/core/peerset/src/lib.rs +++ b/substrate/core/peerset/src/lib.rs @@ -22,7 +22,6 @@ mod slots; use std::collections::VecDeque; use futures::{prelude::*, sync::mpsc, try_ready}; use libp2p::PeerId; -use linked_hash_map::LinkedHashMap; use log::trace; use lru_cache::LruCache; use slots::{SlotType, SlotState, Slots}; diff --git a/substrate/core/sr-io/Cargo.toml b/substrate/core/sr-io/Cargo.toml index 68da47893f..645caf54b2 100644 --- a/substrate/core/sr-io/Cargo.toml +++ b/substrate/core/sr-io/Cargo.toml @@ -11,7 +11,7 @@ rustc_version = "0.2" [dependencies] rstd = { package = "sr-std", path = "../sr-std", default-features = false } primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } -parity-codec = { version = "3.3", default-features = false } +codec = { package="parity-codec", version = "3.3", default-features = false } hash-db = { version = "0.12", default-features = false } libsecp256k1 = { version = "0.2.1", optional = true } tiny-keccak = { version = "1.4.2", optional = true } @@ -23,7 +23,7 @@ trie = { package = "substrate-trie", path = "../trie", optional = true } default = ["std"] std = [ "primitives/std", - "parity-codec/std", + "codec/std", "rstd/std", "hash-db/std", "trie", @@ -34,4 +34,4 @@ std = [ ] nightly = [] strict = [] -wasm-nice-panic-message = [] \ No newline at end of file +wasm-nice-panic-message = [] diff --git a/substrate/core/sr-io/src/lib.rs b/substrate/core/sr-io/src/lib.rs index 6a00e6ca27..5101d3b2c1 100644 --- a/substrate/core/sr-io/src/lib.rs +++ b/substrate/core/sr-io/src/lib.rs @@ -16,6 +16,8 @@ //! This is part of the Substrate runtime. +#![warn(missing_docs)] + #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(lang_items))] #![cfg_attr(not(feature = "std"), feature(alloc_error_handler))] @@ -25,14 +27,231 @@ #![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 hash_db::Hasher; +use rstd::vec::Vec; + +#[doc(hidden)] +pub use codec; + +pub use primitives::Blake2Hasher; + +/// Error verifying ECDSA signature pub enum EcdsaVerifyError { + /// Incorrect value of R or S BadRS, + /// Incorrect value of V BadV, + /// Invalid signature BadSignature, } -#[cfg(feature = "std")] -include!("../with_std.rs"); +/// Trait for things which can be printed. +pub trait Printable { + /// Print the object. + fn print(self); +} +/// Converts a public trait definition into a private trait and set of public functions +/// that assume the trait is implemented for `()` for ease of calling. +macro_rules! export_api { + ( + $( #[$trait_attr:meta] )* + pub(crate) trait $trait_name:ident { + $( + $( #[$attr:meta] )* + fn $name:ident + $(< $( $g_name:ident $( : $g_ty:path )? ),+ >)? + ( $( $arg:ident : $arg_ty:ty ),* ) + $( -> $ret:ty )? + $( where $( $w_name:path : $w_ty:path ),+ )?; + )* + } + ) => { + $( #[$trait_attr] )* + pub(crate) trait $trait_name { + $( + $( #[$attr] )* + fn $name $(< $( $g_name $( : $g_ty )? ),+ >)? ( $($arg : $arg_ty ),* ) $( -> $ret )? + $( where $( $w_name : $w_ty ),+ )?; + )* + } + + $( + $( #[$attr] )* + pub fn $name $(< $( $g_name $( : $g_ty )? ),+ >)? ( $($arg : $arg_ty ),* ) $( -> $ret )? + $( where $( $w_name : $w_ty ),+ )? + { + #[allow(deprecated)] + <()>:: $name $(::< $( $g_name ),+ > )? ( $( $arg ),* ) + } + )* + } +} + +export_api! { + pub(crate) trait StorageApi { + /// Get `key` from storage and return a `Vec`, empty if there's a problem. + fn storage(key: &[u8]) -> Option>; + + /// Get `key` from child storage and return a `Vec`, empty if there's a problem. + fn child_storage(storage_key: &[u8], key: &[u8]) -> Option>; + + /// Get `key` from storage, placing the value into `value_out` (as much of it as possible) and return + /// the number of bytes that the entry in storage had beyond the offset or None if the storage entry + /// doesn't exist at all. Note that if the buffer is smaller than the storage entry length, the returned + /// number of bytes is not equal to the number of bytes written to the `value_out`. + fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option; + + /// Get `key` from child storage, placing the value into `value_out` (as much of it as possible) and return + /// the number of bytes that the entry in storage had beyond the offset or None if the storage entry + /// doesn't exist at all. Note that if the buffer is smaller than the storage entry length, the returned + /// number of bytes is not equal to the number of bytes written to the `value_out`. + fn read_child_storage(storage_key: &[u8], key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option; + + /// Set the storage of some particular key to Some value. + fn set_storage(key: &[u8], value: &[u8]); + + /// Set the child storage of some particular key to Some value. + fn set_child_storage(storage_key: &[u8], key: &[u8], value: &[u8]); + + /// Clear the storage of a key. + fn clear_storage(key: &[u8]); + + /// Clear the storage of a key. + fn clear_child_storage(storage_key: &[u8], key: &[u8]); + + /// Clear an entire child storage. + fn kill_child_storage(storage_key: &[u8]); + + /// Check whether a given `key` exists in storage. + fn exists_storage(key: &[u8]) -> bool; + + /// Check whether a given `key` exists in storage. + fn exists_child_storage(storage_key: &[u8], key: &[u8]) -> bool; + + /// Clear the storage entries with a key that starts with the given prefix. + fn clear_prefix(prefix: &[u8]); + + /// "Commit" all existing operations and compute the resultant storage root. + fn storage_root() -> [u8; 32]; + + /// "Commit" all existing operations and compute the resultant child storage root. + fn child_storage_root(storage_key: &[u8]) -> Vec; + + /// "Commit" all existing operations and get the resultant storage change root. + fn storage_changes_root(parent_hash: [u8; 32], parent_num: u64) -> Option<[u8; 32]>; + + /// A trie root formed from the enumerated items. + /// TODO [#2382] remove (just use `ordered_trie_root` (NOTE currently not implemented for without_std)) + fn enumerated_trie_root(input: &[&[u8]]) -> H::Out + where + H: Hasher, + H: self::imp::HasherBounds, + H::Out: Ord + ; + + /// A trie root formed from the iterated items. + fn trie_root(input: I) -> H::Out + where + I: IntoIterator, + A: AsRef<[u8]>, + A: Ord, + B: AsRef<[u8]>, + H: Hasher, + H: self::imp::HasherBounds, + H::Out: Ord + ; + + /// A trie root formed from the enumerated items. + fn ordered_trie_root(input: I) -> H::Out + where + I: IntoIterator, + A: AsRef<[u8]>, + H: Hasher, + H: self::imp::HasherBounds, + H::Out: Ord + ; + } +} + +export_api! { + pub(crate) trait OtherApi { + /// The current relay chain identifier. + fn chain_id() -> u64; + + /// Print a printable value. + fn print(value: T) + where + T: Printable, + T: Sized + ; + } +} + +export_api! { + pub(crate) trait CryptoApi { + /// Verify a ed25519 signature. + fn ed25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool; + + /// Verify an sr25519 signature. + fn sr25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool; + + /// Verify and recover a SECP256k1 ECDSA signature. + /// - `sig` is passed in RSV format. V should be either 0/1 or 27/28. + /// - returns `Err` if the signature is bad, otherwise the 64-byte pubkey (doesn't include the 0x04 prefix). + fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError>; + } +} + +export_api! { + pub(crate) trait HashingApi { + /// Conduct a 256-bit Keccak hash. + fn keccak_256(data: &[u8]) -> [u8; 32] ; + + /// Conduct a 128-bit Blake2 hash. + fn blake2_128(data: &[u8]) -> [u8; 16]; + + /// Conduct a 256-bit Blake2 hash. + fn blake2_256(data: &[u8]) -> [u8; 32]; + + /// Conduct four XX hashes to give a 256-bit result. + fn twox_256(data: &[u8]) -> [u8; 32]; + + /// Conduct two XX hashes to give a 128-bit result. + fn twox_128(data: &[u8]) -> [u8; 16]; + + /// Conduct two XX hashes to give a 64-bit result. + fn twox_64(data: &[u8]) -> [u8; 8]; + } +} + +export_api! { + pub(crate) trait OffchainApi { + /// Submit extrinsic from the runtime. + /// + /// Depending on the kind of extrinsic it will either be: + /// 1. scheduled to be included in the next produced block (inherent) + /// 2. added to the pool and propagated (transaction) + fn submit_extrinsic(data: &T); + } +} + +/// API trait that should cover all other APIs. +/// +/// Implement this to make sure you implement all APIs. +trait Api: StorageApi + OtherApi + CryptoApi + HashingApi + OffchainApi {} + +mod imp { + use super::*; + + #[cfg(feature = "std")] + include!("../with_std.rs"); + + #[cfg(not(feature = "std"))] + include!("../without_std.rs"); +} + +#[cfg(feature = "std")] +pub use self::imp::{StorageOverlay, ChildrenStorageOverlay, with_storage, with_externalities, TestExternalities}; #[cfg(not(feature = "std"))] -include!("../without_std.rs"); +pub use self::imp::ext::*; diff --git a/substrate/core/sr-io/with_std.rs b/substrate/core/sr-io/with_std.rs index 3148cf2842..d73ccf4b66 100644 --- a/substrate/core/sr-io/with_std.rs +++ b/substrate/core/sr-io/with_std.rs @@ -14,14 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -#[doc(hidden)] -pub use parity_codec as codec; -// re-export hashing functions. -pub use primitives::{ +use primitives::{ blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair }; -pub use tiny_keccak::keccak256 as keccak_256; // Switch to this after PoC-3 // pub use primitives::BlakeHasher; pub use substrate_state_machine::{ @@ -33,18 +29,15 @@ pub use substrate_state_machine::{ use environmental::environmental; use primitives::{hexdisplay::HexDisplay, H256}; -use hash_db::Hasher; #[cfg(feature = "std")] use std::collections::HashMap; environmental!(ext: trait Externalities); -/// A set of key value pairs for storage. -pub type StorageOverlay = HashMap, Vec>; - -/// A set of key value pairs for children storage; -pub type ChildrenStorageOverlay = HashMap, StorageOverlay>; +/// Additional bounds for `Hasher` trait for with_std. +pub trait HasherBounds {} +impl HasherBounds for T {} /// Returns a `ChildStorageKey` if the given `storage_key` slice is a valid storage /// key or panics otherwise. @@ -58,208 +51,216 @@ fn child_storage_key_or_panic(storage_key: &[u8]) -> ChildStorageKey Option> { - ext::with(|ext| ext.storage(key).map(|s| s.to_vec())) +impl StorageApi for () { + fn storage(key: &[u8]) -> Option> { + ext::with(|ext| ext.storage(key).map(|s| s.to_vec())) + .expect("storage cannot be called outside of an Externalities-provided environment.") + } + + fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { + ext::with(|ext| ext.storage(key).map(|value| { + let value = &value[value_offset..]; + let written = std::cmp::min(value.len(), value_out.len()); + value_out[..written].copy_from_slice(&value[..written]); + value.len() + })).expect("read_storage cannot be called outside of an Externalities-provided environment.") + } + + fn child_storage(storage_key: &[u8], key: &[u8]) -> Option> { + ext::with(|ext| { + let storage_key = child_storage_key_or_panic(storage_key); + ext.child_storage(storage_key, key).map(|s| s.to_vec()) + }) .expect("storage cannot be called outside of an Externalities-provided environment.") + } + + fn set_storage(key: &[u8], value: &[u8]) { + ext::with(|ext| + ext.set_storage(key.to_vec(), value.to_vec()) + ); + } + + fn read_child_storage( + storage_key: &[u8], + key: &[u8], + value_out: &mut [u8], + value_offset: usize, + ) -> Option { + ext::with(|ext| { + let storage_key = child_storage_key_or_panic(storage_key); + ext.child_storage(storage_key, key) + .map(|value| { + let value = &value[value_offset..]; + let written = std::cmp::min(value.len(), value_out.len()); + value_out[..written].copy_from_slice(&value[..written]); + value.len() + }) + }) + .expect("read_child_storage cannot be called outside of an Externalities-provided environment.") + } + + fn set_child_storage(storage_key: &[u8], key: &[u8], value: &[u8]) { + ext::with(|ext| { + let storage_key = child_storage_key_or_panic(storage_key); + ext.set_child_storage(storage_key, key.to_vec(), value.to_vec()) + }); + } + + fn clear_storage(key: &[u8]) { + ext::with(|ext| + ext.clear_storage(key) + ); + } + + fn clear_child_storage(storage_key: &[u8], key: &[u8]) { + ext::with(|ext| { + let storage_key = child_storage_key_or_panic(storage_key); + ext.clear_child_storage(storage_key, key) + }); + } + + fn kill_child_storage(storage_key: &[u8]) { + ext::with(|ext| { + let storage_key = child_storage_key_or_panic(storage_key); + ext.kill_child_storage(storage_key) + }); + } + + fn exists_storage(key: &[u8]) -> bool { + ext::with(|ext| + ext.exists_storage(key) + ).unwrap_or(false) + } + + fn exists_child_storage(storage_key: &[u8], key: &[u8]) -> bool { + ext::with(|ext| { + let storage_key = child_storage_key_or_panic(storage_key); + ext.exists_child_storage(storage_key, key) + }).unwrap_or(false) + } + + fn clear_prefix(prefix: &[u8]) { + ext::with(|ext| + ext.clear_prefix(prefix) + ); + } + + fn storage_root() -> [u8; 32] { + ext::with(|ext| + ext.storage_root() + ).unwrap_or(H256::zero()).into() + } + + fn child_storage_root(storage_key: &[u8]) -> Vec { + ext::with(|ext| { + let storage_key = child_storage_key_or_panic(storage_key); + ext.child_storage_root(storage_key) + }).expect("child_storage_root cannot be called outside of an Externalities-provided environment.") + } + + fn storage_changes_root(parent_hash: [u8; 32], parent_num: u64) -> Option<[u8; 32]> { + ext::with(|ext| + ext.storage_changes_root(parent_hash.into(), parent_num).map(Into::into) + ).unwrap_or(None) + } + + fn enumerated_trie_root(input: &[&[u8]]) -> H::Out + where + H: Hasher, + H::Out: Ord, + { + trie::ordered_trie_root::(input.iter()) + } + + fn trie_root(input: I) -> H::Out + where + I: IntoIterator, + A: AsRef<[u8]> + Ord, + B: AsRef<[u8]>, + H: Hasher, + H::Out: Ord, + { + trie::trie_root::(input) + } + + fn ordered_trie_root(input: I) -> H::Out + where + I: IntoIterator, + A: AsRef<[u8]>, + H: Hasher, + H::Out: Ord, + { + trie::ordered_trie_root::(input) + } } -/// Get `key` from child storage and return a `Vec`, empty if there's a problem. -pub fn child_storage(storage_key: &[u8], key: &[u8]) -> Option> { - ext::with(|ext| { - let storage_key = child_storage_key_or_panic(storage_key); - ext.child_storage(storage_key, key).map(|s| s.to_vec()) - }) - .expect("storage cannot be called outside of an Externalities-provided environment.") +impl OtherApi for () { + fn chain_id() -> u64 { + ext::with(|ext| + ext.chain_id() + ).unwrap_or(0) + } + + fn print(value: T) { + value.print() + } } -/// Get `key` from storage, placing the value into `value_out` (as much of it as possible) and return -/// the number of bytes that the entry in storage had beyond the offset or None if the storage entry -/// doesn't exist at all. Note that if the buffer is smaller than the storage entry length, the returned -/// number of bytes is not equal to the number of bytes written to the `value_out`. -pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { - ext::with(|ext| ext.storage(key).map(|value| { - let value = &value[value_offset..]; - let written = ::std::cmp::min(value.len(), value_out.len()); - value_out[..written].copy_from_slice(&value[..written]); - value.len() - })).expect("read_storage cannot be called outside of an Externalities-provided environment.") +impl CryptoApi for () { + fn ed25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { + ed25519::Pair::verify_weak(sig, msg, pubkey) + } + + fn sr25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { + sr25519::Pair::verify_weak(sig, msg, pubkey) + } + + fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError> { + let rs = secp256k1::Signature::parse_slice(&sig[0..64]).map_err(|_| EcdsaVerifyError::BadRS)?; + let v = secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8).map_err(|_| EcdsaVerifyError::BadV)?; + let pubkey = secp256k1::recover(&secp256k1::Message::parse(msg), &rs, &v).map_err(|_| EcdsaVerifyError::BadSignature)?; + let mut res = [0u8; 64]; + res.copy_from_slice(&pubkey.serialize()[1..65]); + Ok(res) + } } -/// Get `key` from child storage, placing the value into `value_out` (as much of it as possible) and return -/// the number of bytes that the entry in storage had beyond the offset or None if the storage entry -/// doesn't exist at all. Note that if the buffer is smaller than the storage entry length, the returned -/// number of bytes is not equal to the number of bytes written to the `value_out`. -pub fn read_child_storage( - storage_key: &[u8], - key: &[u8], - value_out: &mut [u8], - value_offset: usize, -) -> Option { - ext::with(|ext| { - let storage_key = child_storage_key_or_panic(storage_key); - ext.child_storage(storage_key, key) - .map(|value| { - let value = &value[value_offset..]; - let written = ::std::cmp::min(value.len(), value_out.len()); - value_out[..written].copy_from_slice(&value[..written]); - value.len() - }) - }) - .expect("read_child_storage cannot be called outside of an Externalities-provided environment.") +impl HashingApi for () { + fn keccak_256(data: &[u8]) -> [u8; 32] { + tiny_keccak::keccak256(data) + } + + fn blake2_128(data: &[u8]) -> [u8; 16] { + blake2_128(data) + } + + fn blake2_256(data: &[u8]) -> [u8; 32] { + blake2_256(data) + } + + fn twox_256(data: &[u8]) -> [u8; 32] { + twox_256(data) + } + + fn twox_128(data: &[u8]) -> [u8; 16] { + twox_128(data) + } + + fn twox_64(data: &[u8]) -> [u8; 8] { + twox_64(data) + } } -/// Set the storage of a key to some value. -pub fn set_storage(key: &[u8], value: &[u8]) { - ext::with(|ext| - ext.set_storage(key.to_vec(), value.to_vec()) - ); +impl OffchainApi for () { + fn submit_extrinsic(data: &T) { + ext::with(|ext| ext + .submit_extrinsic(codec::Encode::encode(data)) + .expect("submit_extrinsic can be called only in offchain worker context") + ).expect("submit_extrinsic cannot be called outside of an Externalities-provided environment.") + } } -/// Set the child storage of a key to some value. -pub fn set_child_storage(storage_key: &[u8], key: &[u8], value: &[u8]) { - ext::with(|ext| { - let storage_key = child_storage_key_or_panic(storage_key); - ext.set_child_storage(storage_key, key.to_vec(), value.to_vec()) - }); -} - -/// Clear the storage of a key. -pub fn clear_storage(key: &[u8]) { - ext::with(|ext| - ext.clear_storage(key) - ); -} - -/// Clear the storage of a key. -pub fn clear_child_storage(storage_key: &[u8], key: &[u8]) { - ext::with(|ext| { - let storage_key = child_storage_key_or_panic(storage_key); - ext.clear_child_storage(storage_key, key) - }); -} - -/// Check whether a given `key` exists in storage. -pub fn exists_storage(key: &[u8]) -> bool { - ext::with(|ext| - ext.exists_storage(key) - ).unwrap_or(false) -} - -/// Check whether a given `key` exists in storage. -pub fn exists_child_storage(storage_key: &[u8], key: &[u8]) -> bool { - ext::with(|ext| { - let storage_key = child_storage_key_or_panic(storage_key); - ext.exists_child_storage(storage_key, key) - }).unwrap_or(false) -} - -/// Clear the storage entries with a key that starts with the given prefix. -pub fn clear_prefix(prefix: &[u8]) { - ext::with(|ext| - ext.clear_prefix(prefix) - ); -} - -/// Clear an entire child storage. -pub fn kill_child_storage(storage_key: &[u8]) { - ext::with(|ext| { - let storage_key = child_storage_key_or_panic(storage_key); - ext.kill_child_storage(storage_key) - }); -} - -/// The current relay chain identifier. -pub fn chain_id() -> u64 { - ext::with(|ext| - ext.chain_id() - ).unwrap_or(0) -} - -/// "Commit" all existing operations and compute the resultant storage root. -pub fn storage_root() -> H256 { - ext::with(|ext| - ext.storage_root() - ).unwrap_or(H256::zero()) -} - -/// "Commit" all existing operations and compute the resultant child storage root. -pub fn child_storage_root(storage_key: &[u8]) -> Vec { - ext::with(|ext| { - let storage_key = child_storage_key_or_panic(storage_key); - ext.child_storage_root(storage_key) - }).expect("child_storage_root cannot be called outside of an Externalities-provided environment.") -} - -/// "Commit" all existing operations and get the resultant storage change root. -pub fn storage_changes_root(parent_hash: [u8; 32], parent_num: u64) -> Option { - ext::with(|ext| - ext.storage_changes_root(parent_hash.into(), parent_num) - ).unwrap_or(None) -} - -/// A trie root formed from the enumerated items. -// TODO: remove (just use `ordered_trie_root`) -pub fn enumerated_trie_root(input: &[&[u8]]) -> H::Out -where - H: Hasher, - H::Out: Ord, -{ - trie::ordered_trie_root::(input.iter()) -} - -/// A trie root formed from the iterated items. -pub fn trie_root(input: I) -> H::Out -where - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, - H: Hasher, - ::Out: Ord, -{ - trie::trie_root::(input) -} - -/// A trie root formed from the enumerated items. -pub fn ordered_trie_root(input: I) -> H::Out -where - I: IntoIterator + Iterator, - A: AsRef<[u8]>, - H: Hasher, - ::Out: Ord, -{ - trie::ordered_trie_root::(input) -} - -/// Verify a ed25519 signature. -pub fn ed25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { - ed25519::Pair::verify_weak(sig, msg, pubkey) -} - -/// Verify an sr25519 signature. -pub fn sr25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { - sr25519::Pair::verify_weak(sig, msg, pubkey) -} - -/// Verify and recover a SECP256k1 ECDSA signature. -/// - `sig` is passed in RSV format. V should be either 0/1 or 27/28. -/// - returns `Err` if the signature is bad, otherwise the 64-byte pubkey (doesn't include the 0x04 prefix). -pub fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError> { - let rs = secp256k1::Signature::parse_slice(&sig[0..64]).map_err(|_| EcdsaVerifyError::BadRS)?; - let v = secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8).map_err(|_| EcdsaVerifyError::BadV)?; - let pubkey = secp256k1::recover(&secp256k1::Message::parse(msg), &rs, &v).map_err(|_| EcdsaVerifyError::BadSignature)?; - let mut res = [0u8; 64]; - res.copy_from_slice(&pubkey.serialize()[1..65]); - Ok(res) -} - -/// Submit extrinsic. -pub fn submit_extrinsic(data: &T) { - ext::with(|ext| ext - .submit_extrinsic(codec::Encode::encode(data)) - .expect("submit_extrinsic can be called only in offchain worker context") - ).expect("submit_extrinsic cannot be called outside of an Externalities-provided environment.") -} +impl Api for () {} /// Execute the given closure with global function available whose functionality routes into the /// externalities `ext`. Forwards the value that the closure returns. @@ -268,6 +269,12 @@ pub fn with_externalities R>(ext: &mut Externalities, Vec>; + +/// A set of key value pairs for children storage; +pub type ChildrenStorageOverlay = HashMap, StorageOverlay>; + /// Execute the given closure with global functions available whose functionality routes into /// externalities that draw from and populate `storage`. Forwards the value that the closure returns. pub fn with_storage R>(storage: &mut StorageOverlay, f: F) -> R { @@ -279,11 +286,6 @@ pub fn with_storage R>(storage: &mut StorageOverlay, f: F) -> r } -/// Trait for things which can be printed. -pub trait Printable { - fn print(self); -} - impl<'a> Printable for &'a [u8] { fn print(self) { println!("Runtime: {}", HexDisplay::from(&self)); @@ -302,11 +304,6 @@ impl Printable for u64 { } } -/// Print a printable value. -pub fn print(value: T) { - value.print(); -} - #[cfg(test)] mod std_tests { use super::*; diff --git a/substrate/core/sr-io/without_std.rs b/substrate/core/sr-io/without_std.rs index 66ad5541df..b60a3ded1f 100644 --- a/substrate/core/sr-io/without_std.rs +++ b/substrate/core/sr-io/without_std.rs @@ -14,15 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -#[doc(hidden)] -pub use parity_codec as codec; #[doc(hidden)] pub use rstd; pub use rstd::{mem, slice}; use core::{intrinsics, panic::PanicInfo}; use rstd::{vec::Vec, cell::Cell}; -use hash_db::Hasher; use primitives::Blake2Hasher; #[panic_handler] @@ -56,587 +53,584 @@ pub extern fn oom(_: ::core::alloc::Layout) -> ! { } } -/// The state of an exchangeable function. -#[derive(Clone, Copy)] -enum ExchangeableFunctionState { - Original, - Replaced, -} +/// External (Host) APIs +pub mod ext { + use super::*; -/// A function which implementation can be exchanged. -/// -/// Internally this works by swapping function pointers. -pub struct ExchangeableFunction(Cell<(T, ExchangeableFunctionState)>); - -impl ExchangeableFunction { - /// Create a new instance of `ExchangeableFunction`. - pub const fn new(impl_: T) -> Self { - Self(Cell::new((impl_, ExchangeableFunctionState::Original))) + /// The state of an exchangeable function. + #[derive(Clone, Copy)] + enum ExchangeableFunctionState { + /// Original function is present + Original, + /// The function has been replaced. + Replaced, } -} -impl ExchangeableFunction { - /// Replace the implementation with `new_impl`. + /// A function which implementation can be exchanged. /// - /// # Panics - /// - /// Panics when trying to replace an already replaced implementation. - /// - /// # Returns - /// - /// Returns the original implementation wrapped in [`RestoreImplementation`]. - pub fn replace_implementation(&'static self, new_impl: T) -> RestoreImplementation { - if let ExchangeableFunctionState::Replaced = self.0.get().1 { - panic!("Trying to replace an already replaced implementation!") + /// Internally this works by swapping function pointers. + pub struct ExchangeableFunction(Cell<(T, ExchangeableFunctionState)>); + + impl ExchangeableFunction { + /// Create a new instance of `ExchangeableFunction`. + pub const fn new(impl_: T) -> Self { + Self(Cell::new((impl_, ExchangeableFunctionState::Original))) + } + } + + impl ExchangeableFunction { + /// Replace the implementation with `new_impl`. + /// + /// # Panics + /// + /// Panics when trying to replace an already replaced implementation. + /// + /// # Returns + /// + /// Returns the original implementation wrapped in [`RestoreImplementation`]. + pub fn replace_implementation(&'static self, new_impl: T) -> RestoreImplementation { + if let ExchangeableFunctionState::Replaced = self.0.get().1 { + panic!("Trying to replace an already replaced implementation!") + } + + let old = self.0.replace((new_impl, ExchangeableFunctionState::Replaced)); + + RestoreImplementation(self, Some(old.0)) } - let old = self.0.replace((new_impl, ExchangeableFunctionState::Replaced)); + /// Restore the original implementation. + fn restore_orig_implementation(&self, orig: T) { + self.0.set((orig, ExchangeableFunctionState::Original)); + } - RestoreImplementation(self, Some(old.0)) + /// Returns the internal function pointer. + pub fn get(&self) -> T { + self.0.get().0 + } } - /// Restore the original implementation. - fn restore_orig_implementation(&self, orig: T) { - self.0.set((orig, ExchangeableFunctionState::Original)); + // WASM does not support threads, so this is safe; qed. + unsafe impl Sync for ExchangeableFunction {} + + /// Restores a function implementation on drop. + /// + /// Stores a static reference to the function object and the original implementation. + pub struct RestoreImplementation(&'static ExchangeableFunction, Option); + + impl Drop for RestoreImplementation { + fn drop(&mut self) { + self.0.restore_orig_implementation(self.1.take().expect("Value is only taken on drop; qed")); + } } - /// Returns the internal function pointer. - pub fn get(&self) -> T { - self.0.get().0 + /// Ensures we use the right crypto when calling into native + pub trait ExternTrieCrypto: Hasher { + /// Calculate enumerated trie root. + fn enumerated_trie_root(values: &[&[u8]]) -> Self::Out; } -} -// WASM does not support threads, so this is safe; qed. -unsafe impl Sync for ExchangeableFunction {} + /// Additional bounds for Hasher trait for without_std. + pub trait HasherBounds: ExternTrieCrypto {} + impl HasherBounds for T {} -/// Restores a function implementation on drop. -/// -/// Stores a static reference to the function object and the original implementation. -pub struct RestoreImplementation(&'static ExchangeableFunction, Option); - -impl Drop for RestoreImplementation { - fn drop(&mut self) { - self.0.restore_orig_implementation(self.1.take().expect("Value is only taken on drop; qed")); + // Ensures we use a Blake2_256-flavored Hasher when calling into native + impl ExternTrieCrypto for Blake2Hasher { + fn enumerated_trie_root(values: &[&[u8]]) -> Self::Out { + let lengths = values.iter().map(|v| (v.len() as u32).to_le()).collect::>(); + let values = values.iter().fold(Vec::new(), |mut acc, sl| { acc.extend_from_slice(sl); acc }); + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_blake2_256_enumerated_trie_root.get()( + values.as_ptr(), + lengths.as_ptr(), + lengths.len() as u32, + result.as_mut_ptr() + ); + } + result.into() + } } -} -/// Declare extern functions -macro_rules! extern_functions { - ( - $( - $( #[$attr:meta] )* - fn $name:ident ( $( $arg:ident : $arg_ty:ty ),* ) $( -> $ret:ty )?; - )* - ) => { - $( - $( #[$attr] )* - #[allow(non_upper_case_globals)] - pub static $name: ExchangeableFunction $ret )?> = - ExchangeableFunction::new(extern_functions_host_impl::$name); - )* - - /// The exchangeable extern functions host implementations. - mod extern_functions_host_impl { + /// Declare extern functions + macro_rules! extern_functions { + ( $( - pub unsafe fn $name ( $( $arg : $arg_ty ),* ) $( -> $ret )? { - implementation::$name ( $( $arg ),* ) - } + $( #[$attr:meta] )* + fn $name:ident ( $( $arg:ident : $arg_ty:ty ),* ) $( -> $ret:ty )?; + )* + ) => { + $( + $( #[$attr] )* + #[allow(non_upper_case_globals)] + pub static $name: ExchangeableFunction $ret )?> = + ExchangeableFunction::new(extern_functions_host_impl::$name); )* - mod implementation { - extern "C" { - $( - pub fn $name ( $( $arg : $arg_ty ),* ) $( -> $ret )?; - )* + /// The exchangeable extern functions host implementations. + pub(crate) mod extern_functions_host_impl { + $( + pub unsafe fn $name ( $( $arg : $arg_ty ),* ) $( -> $ret )? { + implementation::$name ( $( $arg ),* ) + } + )* + + mod implementation { + extern "C" { + $( + pub fn $name ( $( $arg : $arg_ty ),* ) $( -> $ret )?; + )* + } } } + }; + } + + /// Host functions, provided by the executor. + /// A WebAssembly runtime module would "import" these to access the execution environment + /// (most importantly, storage) or perform heavy hash calculations. + /// See also "ext_" functions in sr-sandbox and sr-std + extern_functions! { + /// Host functions for printing, useful for debugging. + fn ext_print_utf8(utf8_data: *const u8, utf8_len: u32); + /// Print data as hex. + fn ext_print_hex(data: *const u8, len: u32); + /// Print a number + fn ext_print_num(value: u64); + + /// Set value for key in storage. + fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); + /// Remove key and value from storage. + fn ext_clear_storage(key_data: *const u8, key_len: u32); + /// Checks if the given key exists in the storage. + /// + /// # Returns + /// + /// - `1` if the value exists. + /// - `0` if the value does not exists. + fn ext_exists_storage(key_data: *const u8, key_len: u32) -> u32; + /// Remove storage entries which key starts with given prefix. + fn ext_clear_prefix(prefix_data: *const u8, prefix_len: u32); + /// Gets the value of the given key from storage. + /// + /// The host allocates the memory for storing the value. + /// + /// # Returns + /// + /// - `0` if no value exists to the given key. `written_out` is set to `u32::max_value()`. + /// + /// - Otherwise, pointer to the value in memory. `written_out` contains the length of the value. + fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; + /// Gets the value of the given key from storage. + /// + /// The value is written into `value` starting at `value_offset`. + /// + /// If the value length is greater than `value_len - value_offset`, the value is written partially. + /// + /// # Returns + /// + /// - `u32::max_value()` if the value does not exists. + /// + /// - Otherwise, the number of bytes written for value. + fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; + /// Gets the trie root of the storage. + fn ext_storage_root(result: *mut u8); + /// Get the change trie root of the current storage overlay at a block with given parent. + /// + /// # Returns + /// + /// - `1` if the change trie root was found. + /// - `0` if the change trie root was not found. + fn ext_storage_changes_root(parent_hash_data: *const u8, parent_hash_len: u32, parent_num: u64, result: *mut u8) -> u32; + + /// A child storage function. + /// + /// See [`ext_set_storage`] for details. + /// + /// A child storage is used e.g. by a contract. + fn ext_set_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); + /// A child storage function. + /// + /// See [`ext_clear_storage`] for details. + /// + /// A child storage is used e.g. by a contract. + fn ext_clear_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32); + /// A child storage function. + /// + /// See [`ext_exists_storage`] for details. + /// + /// A child storage is used e.g. by a contract. + fn ext_exists_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32) -> u32; + /// A child storage function. + /// + /// See [`ext_kill_storage`] for details. + /// + /// A child storage is used e.g. by a contract. + fn ext_kill_child_storage(storage_key_data: *const u8, storage_key_len: u32); + /// A child storage function. + /// + /// See [`ext_get_allocated_storage`] for details. + /// + /// A child storage is used e.g. by a contract. + fn ext_get_allocated_child_storage( + storage_key_data: *const u8, + storage_key_len: u32, + key_data: *const u8, + key_len: u32, + written_out: *mut u32 + ) -> *mut u8; + /// A child storage function. + /// + /// See [`ext_get_storage_into`] for details. + /// + /// A child storage is used e.g. by a contract. + fn ext_get_child_storage_into( + storage_key_data: *const u8, + storage_key_len: u32, + key_data: *const u8, + key_len: u32, + value_data: *mut u8, + value_len: u32, + value_offset: u32 + ) -> u32; + /// Commits all changes and calculates the child-storage root. + /// + /// A child storage is used e.g. by a contract. + /// + /// # Returns + /// + /// - The pointer to the result vector and `written_out` contains its length. + fn ext_child_storage_root(storage_key_data: *const u8, storage_key_len: u32, written_out: *mut u32) -> *mut u8; + + /// The current relay chain identifier. + fn ext_chain_id() -> u64; + + /// Calculate a blake2_256 merkle trie root. + fn ext_blake2_256_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); + /// BLAKE2_128 hash + fn ext_blake2_128(data: *const u8, len: u32, out: *mut u8); + /// BLAKE2_256 hash + fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); + /// XX64 hash + fn ext_twox_64(data: *const u8, len: u32, out: *mut u8); + /// XX128 hash + fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); + /// XX256 hash + fn ext_twox_256(data: *const u8, len: u32, out: *mut u8); + /// Keccak256 hash + fn ext_keccak_256(data: *const u8, len: u32, out: *mut u8); + /// Note: ext_ed25519_verify returns 0 if the signature is correct, nonzero otherwise. + fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; + /// Note: ext_sr25519_verify returns 0 if the signature is correct, nonzero otherwise. + fn ext_sr25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; + /// Note: ext_secp256k1_ecdsa_recover returns 0 if the signature is correct, nonzero otherwise. + fn ext_secp256k1_ecdsa_recover(msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8) -> u32; + + //================================ + // Offchain-worker Context + //================================ + + /// Submit extrinsic. + fn ext_submit_extrinsic(data: *const u8, len: u32); + } +} + +pub use self::ext::*; + +impl StorageApi for () { + fn storage(key: &[u8]) -> Option> { + let mut length: u32 = 0; + unsafe { + let ptr = ext_get_allocated_storage.get()(key.as_ptr(), key.len() as u32, &mut length); + if length == u32::max_value() { + None + } else { + // Invariants required by Vec::from_raw_parts are not formally fulfilled. + // We don't allocate via String/Vec, but use a custom allocator instead. + // See #300 for more details. + Some(>::from_raw_parts(ptr, length as usize, length as usize)) + } } - }; -} + } -/// Host functions, provided by the executor. -/// A WebAssembly runtime module would "import" these to access the execution environment -/// (most importantly, storage) or perform heavy hash calculations. -/// See also "ext_" functions in sr-sandbox and sr-std -extern_functions! { - /// Host functions for printing, useful for debugging. - fn ext_print_utf8(utf8_data: *const u8, utf8_len: u32); - fn ext_print_hex(data: *const u8, len: u32); - fn ext_print_num(value: u64); + fn child_storage(storage_key: &[u8], key: &[u8]) -> Option> { + let mut length: u32 = 0; + unsafe { + let ptr = ext_get_allocated_child_storage.get()( + storage_key.as_ptr(), + storage_key.len() as u32, + key.as_ptr(), + key.len() as u32, + &mut length + ); + if length == u32::max_value() { + None + } else { + // Invariants required by Vec::from_raw_parts are not formally fulfilled. + // We don't allocate via String/Vec, but use a custom allocator instead. + // See #300 for more details. + Some(>::from_raw_parts(ptr, length as usize, length as usize)) + } + } + } - /// Set value for key in storage. - fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); - /// Remove key and value from storage. - fn ext_clear_storage(key_data: *const u8, key_len: u32); - /// Checks if the given key exists in the storage. - /// - /// # Returns - /// - /// - `1` if the value exists. - /// - `0` if the value does not exists. - fn ext_exists_storage(key_data: *const u8, key_len: u32) -> u32; - /// Remove storage entries which key starts with given prefix. - fn ext_clear_prefix(prefix_data: *const u8, prefix_len: u32); - /// Gets the value of the given key from storage. - /// - /// The host allocates the memory for storing the value. - /// - /// # Returns - /// - /// - `0` if no value exists to the given key. `written_out` is set to `u32::max_value()`. - /// - /// - Otherwise, pointer to the value in memory. `written_out` contains the length of the value. - fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; - /// Gets the value of the given key from storage. - /// - /// The value is written into `value` starting at `value_offset`. - /// - /// If the value length is greater than `value_len - value_offset`, the value is written partially. - /// - /// # Returns - /// - /// - `u32::max_value()` if the value does not exists. - /// - /// - Otherwise, the number of bytes written for value. - fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; - /// Gets the trie root of the storage. - fn ext_storage_root(result: *mut u8); - /// Get the change trie root of the current storage overlay at a block with given parent. - /// - /// # Returns - /// - /// - `1` if the change trie root was found. - /// - `0` if the change trie root was not found. - fn ext_storage_changes_root(parent_hash_data: *const u8, parent_hash_len: u32, parent_num: u64, result: *mut u8) -> u32; + fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { + unsafe { + match ext_get_storage_into.get()( + key.as_ptr(), + key.len() as u32, + value_out.as_mut_ptr(), + value_out.len() as u32, + value_offset as u32, + ) { + none if none == u32::max_value() => None, + length => Some(length as usize), + } + } + } - /// A child storage function. - /// - /// See [`ext_set_storage`] for details. - /// - /// A child storage is used e.g. by a contract. - fn ext_set_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); - /// A child storage function. - /// - /// See [`ext_clear_storage`] for details. - /// - /// A child storage is used e.g. by a contract. - fn ext_clear_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32); - /// A child storage function. - /// - /// See [`ext_exists_storage`] for details. - /// - /// A child storage is used e.g. by a contract. - fn ext_exists_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32) -> u32; - /// A child storage function. - /// - /// See [`ext_kill_storage`] for details. - /// - /// A child storage is used e.g. by a contract. - fn ext_kill_child_storage(storage_key_data: *const u8, storage_key_len: u32); - /// A child storage function. - /// - /// See [`ext_get_allocated_storage`] for details. - /// - /// A child storage is used e.g. by a contract. - fn ext_get_allocated_child_storage( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - written_out: *mut u32 - ) -> *mut u8; - /// A child storage function. - /// - /// See [`ext_get_storage_into`] for details. - /// - /// A child storage is used e.g. by a contract. - fn ext_get_child_storage_into( - storage_key_data: *const u8, - storage_key_len: u32, - key_data: *const u8, - key_len: u32, - value_data: *mut u8, - value_len: u32, - value_offset: u32 - ) -> u32; - /// Commits all changes and calculates the child-storage root. - /// - /// A child storage is used e.g. by a contract. - /// - /// # Returns - /// - /// - The pointer to the result vector and `written_out` contains its length. - fn ext_child_storage_root(storage_key_data: *const u8, storage_key_len: u32, written_out: *mut u32) -> *mut u8; + fn read_child_storage(storage_key: &[u8], key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { + unsafe { + match ext_get_child_storage_into.get()( + storage_key.as_ptr(), storage_key.len() as u32, + key.as_ptr(), key.len() as u32, + value_out.as_mut_ptr(), value_out.len() as u32, + value_offset as u32 + ) { + none if none == u32::max_value() => None, + length => Some(length as usize), + } + } + } - /// The current relay chain identifier. - fn ext_chain_id() -> u64; + fn set_storage(key: &[u8], value: &[u8]) { + unsafe { + ext_set_storage.get()( + key.as_ptr(), key.len() as u32, + value.as_ptr(), value.len() as u32 + ); + } + } - /// Hash calculation and verification - fn ext_blake2_256_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); - fn ext_blake2_128(data: *const u8, len: u32, out: *mut u8); - fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); - fn ext_twox_64(data: *const u8, len: u32, out: *mut u8); - fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); - fn ext_twox_256(data: *const u8, len: u32, out: *mut u8); - fn ext_keccak_256(data: *const u8, len: u32, out: *mut u8); - /// Note: ext_ed25519_verify returns 0 if the signature is correct, nonzero otherwise. - fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; - /// Note: ext_sr25519_verify returns 0 if the signature is correct, nonzero otherwise. - fn ext_sr25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; - /// Note: ext_secp256k1_ecdsa_recover returns 0 if the signature is correct, nonzero otherwise. - fn ext_secp256k1_ecdsa_recover(msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8) -> u32; + fn set_child_storage(storage_key: &[u8], key: &[u8], value: &[u8]) { + unsafe { + ext_set_child_storage.get()( + storage_key.as_ptr(), storage_key.len() as u32, + key.as_ptr(), key.len() as u32, + value.as_ptr(), value.len() as u32 + ); + } + } - //================================ - // Offchain-worker Context - //================================ + fn clear_storage(key: &[u8]) { + unsafe { + ext_clear_storage.get()( + key.as_ptr(), key.len() as u32 + ); + } + } - /// Submit extrinsic. - fn ext_submit_extrinsic(data: *const u8, len: u32); -} + fn clear_child_storage(storage_key: &[u8], key: &[u8]) { + unsafe { + ext_clear_child_storage.get()( + storage_key.as_ptr(), storage_key.len() as u32, + key.as_ptr(), key.len() as u32 + ); + } + } -/// Ensures we use the right crypto when calling into native -pub trait ExternTrieCrypto { - fn enumerated_trie_root(values: &[&[u8]]) -> [u8; 32]; -} + fn exists_storage(key: &[u8]) -> bool { + unsafe { + ext_exists_storage.get()( + key.as_ptr(), key.len() as u32 + ) != 0 + } + } -// Ensures we use a Blake2_256-flavored Hasher when calling into native -impl ExternTrieCrypto for Blake2Hasher { - fn enumerated_trie_root(values: &[&[u8]]) -> [u8; 32] { - let lengths = values.iter().map(|v| (v.len() as u32).to_le()).collect::>(); - let values = values.iter().fold(Vec::new(), |mut acc, sl| { acc.extend_from_slice(sl); acc }); + fn exists_child_storage(storage_key: &[u8], key: &[u8]) -> bool { + unsafe { + ext_exists_child_storage.get()( + storage_key.as_ptr(), storage_key.len() as u32, + key.as_ptr(), key.len() as u32 + ) != 0 + } + } + + fn clear_prefix(prefix: &[u8]) { + unsafe { + ext_clear_prefix.get()( + prefix.as_ptr(), + prefix.len() as u32 + ); + } + } + + fn kill_child_storage(storage_key: &[u8]) { + unsafe { + ext_kill_child_storage.get()( + storage_key.as_ptr(), + storage_key.len() as u32 + ); + } + } + + fn storage_root() -> [u8; 32] { let mut result: [u8; 32] = Default::default(); unsafe { - ext_blake2_256_enumerated_trie_root.get()( - values.as_ptr(), - lengths.as_ptr(), - lengths.len() as u32, - result.as_mut_ptr() + ext_storage_root.get()(result.as_mut_ptr()); + } + result + } + + fn child_storage_root(storage_key: &[u8]) -> Vec { + let mut length: u32 = 0; + unsafe { + let ptr = ext_child_storage_root.get()( + storage_key.as_ptr(), + storage_key.len() as u32, + &mut length ); + // Invariants required by Vec::from_raw_parts are not formally fulfilled. + // We don't allocate via String/Vec, but use a custom allocator instead. + // See #300 for more details. + >::from_raw_parts(ptr, length as usize, length as usize) + } + } + + fn storage_changes_root(parent_hash: [u8; 32], parent_num: u64) -> Option<[u8; 32]> { + let mut result: [u8; 32] = Default::default(); + let is_set = unsafe { + ext_storage_changes_root.get()(parent_hash.as_ptr(), parent_hash.len() as u32, parent_num, result.as_mut_ptr()) + }; + + if is_set != 0 { + Some(result) + } else { + None + } + } + + fn enumerated_trie_root(values: &[&[u8]]) -> H::Out { + H::enumerated_trie_root(values) + } + + fn trie_root< + H: Hasher + ExternTrieCrypto, + I: IntoIterator, + A: AsRef<[u8]> + Ord, + B: AsRef<[u8]>, + >(_input: I) -> H::Out { + unimplemented!() + } + + fn ordered_trie_root< + H: Hasher + ExternTrieCrypto, + I: IntoIterator, + A: AsRef<[u8]> + >(_input: I) -> H::Out { + unimplemented!() + } +} + +impl OtherApi for () { + fn chain_id() -> u64 { + unsafe { + ext_chain_id.get()() + } + } + + fn print(value: T) { + value.print() + } + +} + +impl HashingApi for () { + fn keccak_256(data: &[u8]) -> [u8; 32] { + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_keccak_256.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); + } + result + } + + fn blake2_128(data: &[u8]) -> [u8; 16] { + let mut result: [u8; 16] = Default::default(); + unsafe { + ext_blake2_128.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); + } + result + } + + fn blake2_256(data: &[u8]) -> [u8; 32] { + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_blake2_256.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); + } + result + } + + fn twox_256(data: &[u8]) -> [u8; 32] { + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_twox_256.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); + } + result + } + + fn twox_128(data: &[u8]) -> [u8; 16] { + let mut result: [u8; 16] = Default::default(); + unsafe { + ext_twox_128.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); + } + result + } + + fn twox_64(data: &[u8]) -> [u8; 8] { + let mut result: [u8; 8] = Default::default(); + unsafe { + ext_twox_64.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); } result } } -/// Get `key` from storage and return a `Vec`, empty if there's a problem. -pub fn storage(key: &[u8]) -> Option> { - let mut length: u32 = 0; - unsafe { - let ptr = ext_get_allocated_storage.get()(key.as_ptr(), key.len() as u32, &mut length); - if length == u32::max_value() { - None - } else { - // Invariants required by Vec::from_raw_parts are not formally fulfilled. - // We don't allocate via String/Vec, but use a custom allocator instead. - // See #300 for more details. - Some(>::from_raw_parts(ptr, length as usize, length as usize)) +impl CryptoApi for () { + fn ed25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { + unsafe { + ext_ed25519_verify.get()(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ref().as_ptr()) == 0 + } + } + + fn sr25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { + unsafe { + ext_sr25519_verify.get()(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ref().as_ptr()) == 0 + } + } + + fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError> { + let mut pubkey = [0u8; 64]; + match unsafe { + ext_secp256k1_ecdsa_recover.get()(msg.as_ptr(), sig.as_ptr(), pubkey.as_mut_ptr()) + } { + 0 => Ok(pubkey), + 1 => Err(EcdsaVerifyError::BadRS), + 2 => Err(EcdsaVerifyError::BadV), + 3 => Err(EcdsaVerifyError::BadSignature), + _ => unreachable!("`ext_secp256k1_ecdsa_recover` only returns 0, 1, 2 or 3; qed"), } } } -/// Get `key` from child storage and return a `Vec`, empty if there's a problem. -pub fn child_storage(storage_key: &[u8], key: &[u8]) -> Option> { - let mut length: u32 = 0; - unsafe { - let ptr = ext_get_allocated_child_storage.get()( - storage_key.as_ptr(), - storage_key.len() as u32, - key.as_ptr(), - key.len() as u32, - &mut length - ); - if length == u32::max_value() { - None - } else { - // Invariants required by Vec::from_raw_parts are not formally fulfilled. - // We don't allocate via String/Vec, but use a custom allocator instead. - // See #300 for more details. - Some(>::from_raw_parts(ptr, length as usize, length as usize)) +impl OffchainApi for () { + fn submit_extrinsic(data: &T) { + let encoded_data = codec::Encode::encode(data); + unsafe { + ext_submit_extrinsic.get()(encoded_data.as_ptr(), encoded_data.len() as u32) } } } -/// Set the storage of some particular key to Some value. -pub fn set_storage(key: &[u8], value: &[u8]) { - unsafe { - ext_set_storage.get()( - key.as_ptr(), key.len() as u32, - value.as_ptr(), value.len() as u32 - ); - } -} - -/// Set the child storage of some particular key to Some value. -pub fn set_child_storage(storage_key: &[u8], key: &[u8], value: &[u8]) { - unsafe { - ext_set_child_storage.get()( - storage_key.as_ptr(), storage_key.len() as u32, - key.as_ptr(), key.len() as u32, - value.as_ptr(), value.len() as u32 - ); - } -} - -/// Clear the storage of some particular key. -pub fn clear_storage(key: &[u8]) { - unsafe { - ext_clear_storage.get()( - key.as_ptr(), key.len() as u32 - ); - } -} - -/// Clear the storage of some particular key. -pub fn clear_child_storage(storage_key: &[u8], key: &[u8]) { - unsafe { - ext_clear_child_storage.get()( - storage_key.as_ptr(), storage_key.len() as u32, - key.as_ptr(), key.len() as u32 - ); - } -} - -/// Determine whether a particular key exists in storage. -pub fn exists_storage(key: &[u8]) -> bool { - unsafe { - ext_exists_storage.get()( - key.as_ptr(), key.len() as u32 - ) != 0 - } -} - -/// Determine whether a particular key exists in storage. -pub fn exists_child_storage(storage_key: &[u8], key: &[u8]) -> bool { - unsafe { - ext_exists_child_storage.get()( - storage_key.as_ptr(), storage_key.len() as u32, - key.as_ptr(), key.len() as u32 - ) != 0 - } -} - -/// Clear the storage entries key of which starts with the given prefix. -pub fn clear_prefix(prefix: &[u8]) { - unsafe { - ext_clear_prefix.get()( - prefix.as_ptr(), - prefix.len() as u32 - ); - } -} - -/// Clear an entire child storage. -pub fn kill_child_storage(storage_key: &[u8]) { - unsafe { - ext_kill_child_storage.get()( - storage_key.as_ptr(), - storage_key.len() as u32 - ); - } -} - -/// Get `key` from storage, placing the value into `value_out` (as much as possible) and return -/// the number of bytes that the key in storage was beyond the offset. -pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { - unsafe { - match ext_get_storage_into.get()( - key.as_ptr(), - key.len() as u32, - value_out.as_mut_ptr(), - value_out.len() as u32, - value_offset as u32, - ) { - none if none == u32::max_value() => None, - length => Some(length as usize), - } - } -} - -/// Get `key` from child storage, placing the value into `value_out` (as much as possible) and return -/// the number of bytes that the key in storage was beyond the offset. -pub fn read_child_storage(storage_key: &[u8], key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { - unsafe { - match ext_get_child_storage_into.get()( - storage_key.as_ptr(), storage_key.len() as u32, - key.as_ptr(), key.len() as u32, - value_out.as_mut_ptr(), value_out.len() as u32, - value_offset as u32 - ) { - none if none == u32::max_value() => None, - length => Some(length as usize), - } - } -} - -/// The current storage's root. -pub fn storage_root() -> [u8; 32] { - let mut result: [u8; 32] = Default::default(); - unsafe { - ext_storage_root.get()(result.as_mut_ptr()); - } - result -} - -/// "Commit" all existing operations and compute the resultant child storage root. -pub fn child_storage_root(storage_key: &[u8]) -> Vec { - let mut length: u32 = 0; - unsafe { - let ptr = ext_child_storage_root.get()( - storage_key.as_ptr(), - storage_key.len() as u32, - &mut length - ); - // Invariants required by Vec::from_raw_parts are not formally fulfilled. - // We don't allocate via String/Vec, but use a custom allocator instead. - // See #300 for more details. - >::from_raw_parts(ptr, length as usize, length as usize) - } -} - -/// The current storage' changes root. -pub fn storage_changes_root(parent_hash: [u8; 32], parent_num: u64) -> Option<[u8; 32]> { - let mut result: [u8; 32] = Default::default(); - let is_set = unsafe { - ext_storage_changes_root.get()(parent_hash.as_ptr(), parent_hash.len() as u32, parent_num, result.as_mut_ptr()) - }; - - if is_set != 0 { - Some(result) - } else { - None - } -} - -/// A trie root calculated from enumerated values. -pub fn enumerated_trie_root(values: &[&[u8]]) -> [u8; 32] { - H::enumerated_trie_root(values) -} - -/// A trie root formed from the iterated items. -pub fn trie_root< - H: Hasher + ExternTrieCrypto, - I: IntoIterator, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, ->(_input: I) -> [u8; 32] { - unimplemented!() -} - -/// A trie root formed from the enumerated items. -pub fn ordered_trie_root< - H: Hasher + ExternTrieCrypto, - I: IntoIterator, - A: AsRef<[u8]> ->(_input: I) -> [u8; 32] { - unimplemented!() -} - -/// The current relay chain identifier. -pub fn chain_id() -> u64 { - unsafe { - ext_chain_id.get()() - } -} - -/// Conduct a 256-bit Blake2 hash. -pub fn blake2_256(data: &[u8]) -> [u8; 32] { - let mut result: [u8; 32] = Default::default(); - unsafe { - ext_blake2_256.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); - } - result -} - -/// Conduct a 128-bit Blake2 hash. -pub fn blake2_128(data: &[u8]) -> [u8; 16] { - let mut result: [u8; 16] = Default::default(); - unsafe { - ext_blake2_128.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); - } - result -} - -/// Conduct a 256-bit Keccak hash. -pub fn keccak_256(data: &[u8]) -> [u8; 32] { - let mut result: [u8; 32] = Default::default(); - unsafe { - ext_keccak_256.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); - } - result -} - -/// Conduct four XX hashes to give a 256-bit result. -pub fn twox_256(data: &[u8]) -> [u8; 32] { - let mut result: [u8; 32] = Default::default(); - unsafe { - ext_twox_256.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); - } - result -} - -/// Conduct two XX hashes to give a 128-bit result. -pub fn twox_128(data: &[u8]) -> [u8; 16] { - let mut result: [u8; 16] = Default::default(); - unsafe { - ext_twox_128.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); - } - result -} - -/// Conduct two XX hashes to give a 64-bit result. -pub fn twox_64(data: &[u8]) -> [u8; 8] { - let mut result: [u8; 8] = Default::default(); - unsafe { - ext_twox_64.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); - } - result -} - -/// Verify a ed25519 signature. -pub fn ed25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { - unsafe { - ext_ed25519_verify.get()(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ref().as_ptr()) == 0 - } -} - -/// Verify a sr25519 signature. -pub fn sr25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { - unsafe { - ext_sr25519_verify.get()(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ref().as_ptr()) == 0 - } -} - -/// Verify and recover a SECP256k1 ECDSA signature. -/// - `sig` is passed in RSV format. V should be either 0/1 or 27/28. -/// - returns `None` if the signature is bad, the 64-byte pubkey (doesn't include the 0x04 prefix). -pub fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError> { - let mut pubkey = [0u8; 64]; - match unsafe { - ext_secp256k1_ecdsa_recover.get()(msg.as_ptr(), sig.as_ptr(), pubkey.as_mut_ptr()) - } { - 0 => Ok(pubkey), - 1 => Err(EcdsaVerifyError::BadRS), - 2 => Err(EcdsaVerifyError::BadV), - 3 => Err(EcdsaVerifyError::BadSignature), - _ => unreachable!("`ext_secp256k1_ecdsa_recover` only returns 0, 1, 2 or 3; qed"), - } -} - -/// Submit extrinsic from the runtime. -/// -/// Depending on the kind of extrinsic it will either be: -/// 1. scheduled to be included in the next produced block (inherent) -/// 2. added to the pool and propagated (transaction) -pub fn submit_extrinsic(data: &T) { - let encoded_data = codec::Encode::encode(data); - unsafe { - ext_submit_extrinsic.get()(encoded_data.as_ptr(), encoded_data.len() as u32) - } -} - -/// Trait for things which can be printed. -pub trait Printable { - fn print(self); -} +impl Api for () {} impl<'a> Printable for &'a [u8] { fn print(self) { @@ -659,8 +653,3 @@ impl Printable for u64 { unsafe { ext_print_num.get()(self); } } } - -/// Print a printable value. -pub fn print(value: T) { - value.print(); -} diff --git a/substrate/core/test-runtime/wasm/Cargo.lock b/substrate/core/test-runtime/wasm/Cargo.lock index b637940459..e8b4072b43 100644 --- a/substrate/core/test-runtime/wasm/Cargo.lock +++ b/substrate/core/test-runtime/wasm/Cargo.lock @@ -2232,7 +2232,6 @@ name = "srml-support" version = "1.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2280,7 +2279,6 @@ dependencies = [ name = "srml-system" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2488,7 +2486,6 @@ dependencies = [ name = "substrate-keyring" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", "strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2522,7 +2519,6 @@ dependencies = [ "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash256-std-hasher 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2555,7 +2551,6 @@ version = "1.0.0" dependencies = [ "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2588,7 +2583,6 @@ name = "substrate-test-runtime" version = "1.0.0" dependencies = [ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/substrate/node-template/runtime/wasm/Cargo.lock b/substrate/node-template/runtime/wasm/Cargo.lock index c430e34fb8..f061884222 100644 --- a/substrate/node-template/runtime/wasm/Cargo.lock +++ b/substrate/node-template/runtime/wasm/Cargo.lock @@ -2242,7 +2242,6 @@ dependencies = [ name = "srml-aura" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2259,7 +2258,6 @@ dependencies = [ name = "srml-balances" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2274,7 +2272,6 @@ dependencies = [ name = "srml-consensus" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2302,7 +2299,6 @@ dependencies = [ name = "srml-indices" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2329,7 +2325,6 @@ dependencies = [ name = "srml-session" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2345,7 +2340,6 @@ dependencies = [ name = "srml-staking" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2363,7 +2357,6 @@ dependencies = [ name = "srml-sudo" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2378,7 +2371,6 @@ name = "srml-support" version = "1.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2426,7 +2418,6 @@ dependencies = [ name = "srml-system" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2441,7 +2432,6 @@ dependencies = [ name = "srml-timestamp" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2648,7 +2638,6 @@ dependencies = [ name = "substrate-keyring" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", "strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2682,7 +2671,6 @@ dependencies = [ "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash256-std-hasher 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2715,7 +2703,6 @@ version = "1.0.0" dependencies = [ "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index b765abd380..52bffacebd 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -59,7 +59,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { impl_name: create_runtime_str!("substrate-node"), authoring_version: 10, spec_version: 66, - impl_version: 66, + impl_version: 67, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/node/runtime/wasm/Cargo.lock b/substrate/node/runtime/wasm/Cargo.lock index b14c919bb3..bf68ab8f3f 100644 --- a/substrate/node/runtime/wasm/Cargo.lock +++ b/substrate/node/runtime/wasm/Cargo.lock @@ -1367,7 +1367,6 @@ dependencies = [ name = "node-runtime" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 1.0.0", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2286,7 +2285,6 @@ dependencies = [ name = "srml-aura" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2303,7 +2301,6 @@ dependencies = [ name = "srml-balances" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2318,7 +2315,6 @@ dependencies = [ name = "srml-consensus" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2368,7 +2364,6 @@ dependencies = [ name = "srml-democracy" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2396,7 +2391,6 @@ dependencies = [ name = "srml-finality-tracker" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2427,7 +2421,6 @@ dependencies = [ name = "srml-indices" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2454,7 +2447,6 @@ dependencies = [ name = "srml-session" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2470,7 +2462,6 @@ dependencies = [ name = "srml-staking" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2488,7 +2479,6 @@ dependencies = [ name = "srml-sudo" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2503,7 +2493,6 @@ name = "srml-support" version = "1.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2551,7 +2540,6 @@ dependencies = [ name = "srml-system" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2566,7 +2554,6 @@ dependencies = [ name = "srml-timestamp" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2580,7 +2567,6 @@ dependencies = [ name = "srml-treasury" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", @@ -2798,7 +2784,6 @@ dependencies = [ name = "substrate-keyring" version = "1.0.0" dependencies = [ - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 1.0.0", "strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2832,7 +2817,6 @@ dependencies = [ "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "hash256-std-hasher 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2865,7 +2849,6 @@ version = "1.0.0" dependencies = [ "hash-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",