diff --git a/native-runtime/support/src/lib.rs b/native-runtime/support/src/lib.rs index 348c0b17a9ccb..91005a2f1d773 100644 --- a/native-runtime/support/src/lib.rs +++ b/native-runtime/support/src/lib.rs @@ -24,12 +24,20 @@ extern crate polkadot_primitives as primitives; use std::fmt; use primitives::ed25519; -pub use std::vec::Vec; -pub use std::rc::Rc; -pub use std::cell::RefCell; -pub use std::boxed::Box; +pub use std::vec; +pub use std::rc; +pub use std::cell; +pub use std::boxed; pub use std::slice; -pub use std::mem::{size_of, transmute, swap, uninitialized}; +pub use std::mem; + +/// Prelude of common useful imports. +/// +/// This should include only things which are in the normal std prelude. +pub mod prelude { + pub use std::vec::Vec; + pub use std::boxed::Box; +} pub use polkadot_state_machine::Externalities; diff --git a/primitives/src/hashing.rs b/primitives/src/hashing.rs index f82ec7ef8bf78..e1a4f84a99675 100644 --- a/primitives/src/hashing.rs +++ b/primitives/src/hashing.rs @@ -20,37 +20,37 @@ use blake2_rfc; use twox_hash; /// Do a Blake2 512-bit hash and place result in `dest`. -pub fn blake2_512_into(data: &[u8], dest: &mut[u8; 64]) { +pub fn blake2_512_into(data: &[u8], dest: &mut [u8; 64]) { dest.copy_from_slice(blake2_rfc::blake2b::blake2b(64, &[], data).as_bytes()); } /// Do a Blake2 512-bit hash and return result. pub fn blake2_512(data: &[u8]) -> [u8; 64] { - let mut r: [u8; 64] = unsafe { ::std::mem::uninitialized() }; + let mut r = [0; 64]; blake2_512_into(data, &mut r); r } /// Do a Blake2 256-bit hash and place result in `dest`. -pub fn blake2_256_into(data: &[u8], dest: &mut[u8; 32]) { +pub fn blake2_256_into(data: &[u8], dest: &mut [u8; 32]) { dest.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes()); } /// Do a Blake2 256-bit hash and return result. pub fn blake2_256(data: &[u8]) -> [u8; 32] { - let mut r: [u8; 32] = unsafe { ::std::mem::uninitialized() }; + let mut r = [0; 32]; blake2_256_into(data, &mut r); r } /// Do a Blake2 128-bit hash and place result in `dest`. -pub fn blake2_128_into(data: &[u8], dest: &mut[u8; 16]) { +pub fn blake2_128_into(data: &[u8], dest: &mut [u8; 16]) { dest.copy_from_slice(blake2_rfc::blake2b::blake2b(16, &[], data).as_bytes()); } /// Do a Blake2 128-bit hash and return result. pub fn blake2_128(data: &[u8]) -> [u8; 16] { - let mut r: [u8; 16] = unsafe { ::std::mem::uninitialized() }; + let mut r = [0; 16]; blake2_128_into(data, &mut r); r } diff --git a/wasm-runtime/polkadot/src/codec/endiansensitive.rs b/wasm-runtime/polkadot/src/codec/endiansensitive.rs index a1576284228e9..c4978d5ce4721 100644 --- a/wasm-runtime/polkadot/src/codec/endiansensitive.rs +++ b/wasm-runtime/polkadot/src/codec/endiansensitive.rs @@ -17,7 +17,8 @@ //! Endian manager. /// Trait to allow conversion to a know endian representation when sensitive. -pub trait EndianSensitive: Sized { +// note: the copy bound and static lifetimes are necessary for safety of `Slicable` blanket implementation. +pub trait EndianSensitive: Copy + 'static { fn to_le(self) -> Self { self } fn to_be(self) -> Self { self } fn from_le(self) -> Self { self } @@ -48,3 +49,20 @@ impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); impl_non_endians!(u8, i8, [u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); + +#[cfg(test)] +mod tests { + use super::EndianSensitive; + + #[test] + fn endian_sensitive_is_copy() { + fn _takes_copy() { } + fn _takes_endian_sensitive() { _takes_copy::() } + } + + #[test] + fn endian_sensitive_outlives_static() { + fn _takes_static() { } + fn _takes_endian_sensitive() { _takes_static::() } + } +} diff --git a/wasm-runtime/polkadot/src/codec/joiner.rs b/wasm-runtime/polkadot/src/codec/joiner.rs index 92a5aa87fca97..7fdb1e16456c6 100644 --- a/wasm-runtime/polkadot/src/codec/joiner.rs +++ b/wasm-runtime/polkadot/src/codec/joiner.rs @@ -16,7 +16,7 @@ //! Vec serialiser. -use runtime_support::Vec; +use runtime_support::prelude::*; use slicable::Slicable; /// Trait to allow itself to be serialised into a `Vec` diff --git a/wasm-runtime/polkadot/src/codec/keyedvec.rs b/wasm-runtime/polkadot/src/codec/keyedvec.rs index 1f803b7c6206e..210606ab7c923 100644 --- a/wasm-runtime/polkadot/src/codec/keyedvec.rs +++ b/wasm-runtime/polkadot/src/codec/keyedvec.rs @@ -16,7 +16,7 @@ //! Serialiser and prepender. -use runtime_support::Vec; +use runtime_support::prelude::*; use slicable::Slicable; /// Trait to allow itselg to be serialised and prepended by a given slice. diff --git a/wasm-runtime/polkadot/src/codec/slicable.rs b/wasm-runtime/polkadot/src/codec/slicable.rs index 5ec042ec9bf5a..40f8a532b7131 100644 --- a/wasm-runtime/polkadot/src/codec/slicable.rs +++ b/wasm-runtime/polkadot/src/codec/slicable.rs @@ -16,7 +16,8 @@ //! Serialisation. -use runtime_support::{Vec, size_of, transmute, uninitialized, slice}; +use runtime_support::prelude::*; +use runtime_support::{mem, slice}; use joiner::Joiner; use endiansensitive::EndianSensitive; @@ -33,7 +34,7 @@ pub trait Slicable: Sized { fn to_vec(&self) -> Vec { self.as_slice_then(|s| s.to_vec()) } - fn set_as_slice bool>(set_slice: F) -> Option; + fn set_as_slice bool>(set_slice: F) -> Option; fn as_slice_then R>(&self, f: F) -> R { f(&self.to_vec()) } @@ -44,11 +45,12 @@ pub trait Slicable: Sized { pub trait NonTrivialSlicable: Slicable {} impl Slicable for T { - fn set_as_slice bool>(fill_slice: F) -> Option { - let size = size_of::(); - let mut result: T = unsafe { uninitialized() }; + fn set_as_slice bool>(fill_slice: F) -> Option { + let size = mem::size_of::(); + let mut result: T = unsafe { mem::zeroed() }; let result_slice = unsafe { - slice::from_raw_parts_mut(transmute::<*mut T, *mut u8>(&mut result), size) + let ptr = &mut result as *mut _ as *mut u8; + slice::from_raw_parts_mut(ptr, size) }; if fill_slice(result_slice) { Some(result.from_le()) @@ -57,16 +59,17 @@ impl Slicable for T { } } fn as_slice_then R>(&self, f: F) -> R { - let size = size_of::(); + let size = mem::size_of::(); self.as_le_then(|le| { let value_slice = unsafe { - slice::from_raw_parts(transmute::<*const Self, *const u8>(le), size) + let ptr = le as *const _ as *const u8; + slice::from_raw_parts(ptr, size) }; f(value_slice) }) } fn size_of(_value: &[u8]) -> Option { - Some(size_of::()) + Some(mem::size_of::()) } } @@ -74,7 +77,7 @@ impl Slicable for Vec { fn from_slice(value: &[u8]) -> Option { Some(value[4..].to_vec()) } - fn set_as_slice bool>(_fill_slice: F) -> Option { + fn set_as_slice bool>(_fill_slice: F) -> Option { unimplemented!(); } fn to_vec(&self) -> Vec { diff --git a/wasm-runtime/polkadot/src/codec/streamreader.rs b/wasm-runtime/polkadot/src/codec/streamreader.rs index 371ceed4eeac4..33056a5ac391c 100644 --- a/wasm-runtime/polkadot/src/codec/streamreader.rs +++ b/wasm-runtime/polkadot/src/codec/streamreader.rs @@ -20,13 +20,13 @@ use slicable::Slicable; /// Simple deserialiser. pub struct StreamReader<'a> { - data: &'a[u8], + data: &'a [u8], offset: usize, } impl<'a> StreamReader<'a> { /// Create a new deserialiser based on the `data`. - pub fn new(data: &'a[u8]) -> Self { + pub fn new(data: &'a [u8]) -> Self { StreamReader { data: data, offset: 0, diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 7a96b6cee4437..a08cc046d36bd 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -34,7 +34,7 @@ pub use support::{primitives, function, environment, storable}; #[cfg(test)] pub use support::{testing, statichex}; -use runtime_support::Vec; +use runtime_support::prelude::*; use slicable::Slicable; use primitives::{Block, UncheckedTransaction}; diff --git a/wasm-runtime/polkadot/src/runtime/consensus.rs b/wasm-runtime/polkadot/src/runtime/consensus.rs index 1e12135806f22..689fdca21e682 100644 --- a/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -16,7 +16,7 @@ //! Conensus module for runtime; manages the authority set ready for the native code. -use runtime_support::Vec; +use runtime_support::prelude::*; use storable::StorageVec; use primitives::SessionKey; diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 907b3e16b162e..6914bdc655883 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -17,7 +17,7 @@ //! Session manager: is told the validators and allows them to manage their session keys for the //! consensus module. -use runtime_support::Vec; +use runtime_support::prelude::*; use keyedvec::KeyedVec; use storable::{kill, Storable, StorageVec}; use primitives::{AccountID, SessionKey, BlockNumber}; diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index fc7c12798e3ed..9b0c659f5c9ab 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -16,7 +16,7 @@ //! Staking manager: Handles balances and periodically determines the best set of validators. -use runtime_support::Vec; +use runtime_support::prelude::*; use keyedvec::KeyedVec; use storable::{Storable, StorageVec}; use primitives::{BlockNumber, AccountID}; diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 5ffa03ed818a7..072e17df010c9 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -18,7 +18,8 @@ //! and depositing logs. use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder, Hashable}; -use runtime_support::{Vec, swap}; +use runtime_support::mem; +use runtime_support::prelude::*; use storable::Storable; use keyedvec::KeyedVec; use environment::with_env; @@ -46,7 +47,7 @@ pub fn execute_block(mut block: Block) { // populate environment from header. with_env(|e| { e.block_number = block.header.number; - swap(&mut e.digest, &mut block.header.digest); + mem::swap(&mut e.digest, &mut block.header.digest); e.next_log_index = 0; }); diff --git a/wasm-runtime/polkadot/src/support/environment.rs b/wasm-runtime/polkadot/src/support/environment.rs index 02c29afc1bf69..1011b3168b80f 100644 --- a/wasm-runtime/polkadot/src/support/environment.rs +++ b/wasm-runtime/polkadot/src/support/environment.rs @@ -16,7 +16,11 @@ //! Environment API: Allows certain information to be accessed throughout the runtime. -use runtime_support::{Rc, RefCell, transmute, Box}; +use runtime_support::boxed::Box; +use runtime_support::mem; +use runtime_support::cell::RefCell; +use runtime_support::rc::Rc; + use primitives::{BlockNumber, Digest}; #[derive(Default)] @@ -48,7 +52,7 @@ fn env() -> Rc> { let singleton: Rc> = Rc::new(RefCell::new(Default::default())); // Put it in the heap so it can outlive this call - SINGLETON = transmute(Box::new(singleton)); + SINGLETON = mem::transmute(Box::new(singleton)); } // Now we give out a copy of the data that is safe to use concurrently. @@ -69,7 +73,7 @@ fn env() -> Rc> { let singleton: Rc> = Rc::new(RefCell::new(Default::default())); // Put it in the heap so it can outlive this call - *s.borrow_mut() = transmute(Box::new(singleton)); + *s.borrow_mut() = mem::transmute(Box::new(singleton)); } // Now we give out a copy of the data that is safe to use concurrently. diff --git a/wasm-runtime/polkadot/src/support/primitives.rs b/wasm-runtime/polkadot/src/support/primitives.rs index 3ab385d488933..338be8071050e 100644 --- a/wasm-runtime/polkadot/src/support/primitives.rs +++ b/wasm-runtime/polkadot/src/support/primitives.rs @@ -16,12 +16,12 @@ //! Primitive types. -use runtime_support::Vec; +use runtime_support::prelude::*; use streamreader::StreamReader; use joiner::Joiner; use slicable::{Slicable, NonTrivialSlicable}; use function::Function; -use runtime_support::{size_of, blake2_256, twox_128, twox_256, ed25519_verify}; +use runtime_support::{mem, blake2_256, twox_128, twox_256, ed25519_verify}; #[cfg(test)] use std::fmt; @@ -76,7 +76,7 @@ impl Slicable for Header { }) } - fn set_as_slice bool>(_fill_slice: F) -> Option { + fn set_as_slice bool>(_fill_slice: F) -> Option { unimplemented!(); } @@ -90,7 +90,7 @@ impl Slicable for Header { } fn size_of(data: &[u8]) -> Option { - let first_part = size_of::() + size_of::() + size_of::() + size_of::(); + let first_part = mem::size_of::() + mem::size_of::() + mem::size_of::() + mem::size_of::(); let second_part = >>::size_of(&data[first_part..])?; Some(first_part + second_part) } @@ -122,7 +122,7 @@ impl Slicable for Transaction { }) } - fn set_as_slice bool>(_fill_slice: F) -> Option { + fn set_as_slice bool>(_fill_slice: F) -> Option { unimplemented!(); } @@ -135,7 +135,7 @@ impl Slicable for Transaction { } fn size_of(data: &[u8]) -> Option { - let first_part = size_of::() + size_of::() + size_of::(); + let first_part = mem::size_of::() + mem::size_of::() + mem::size_of::(); let second_part = >::size_of(&data[first_part..])?; Some(first_part + second_part) } @@ -200,7 +200,7 @@ impl Slicable for UncheckedTransaction { }) } - fn set_as_slice bool>(_fill_slice: F) -> Option { + fn set_as_slice bool>(_fill_slice: F) -> Option { unimplemented!(); } @@ -211,7 +211,7 @@ impl Slicable for UncheckedTransaction { } fn size_of(data: &[u8]) -> Option { - let first_part = size_of::<[u8; 64]>(); + let first_part = mem::size_of::<[u8; 64]>(); let second_part = ::size_of(&data[first_part..])?; Some(first_part + second_part) } @@ -237,7 +237,7 @@ impl Slicable for Block { }) } - fn set_as_slice bool>(_fill_slice: F) -> Option { + fn set_as_slice bool>(_fill_slice: F) -> Option { unimplemented!(); } @@ -271,7 +271,7 @@ impl Slicable for Vec { Some(r) } - fn set_as_slice bool>(_fill_slice: F) -> Option { + fn set_as_slice bool>(_fill_slice: F) -> Option { unimplemented!(); } diff --git a/wasm-runtime/polkadot/src/support/storable.rs b/wasm-runtime/polkadot/src/support/storable.rs index 3caf3ed19bfae..9a871a638be5c 100644 --- a/wasm-runtime/polkadot/src/support/storable.rs +++ b/wasm-runtime/polkadot/src/support/storable.rs @@ -19,7 +19,8 @@ use slicable::Slicable; use endiansensitive::EndianSensitive; use keyedvec::KeyedVec; -use runtime_support::{self, twox_128, Vec}; +use runtime_support::prelude::*; +use runtime_support::{self, twox_128}; /// Trait for a value which may be stored in the storage DB. pub trait Storable { @@ -36,7 +37,7 @@ pub trait Storable { /// Remove `key` from storage. pub fn kill(key: &[u8]) { runtime_support::set_storage(&twox_128(key)[..], b""); } -impl Storable for T { +impl Storable for T { fn lookup(key: &[u8]) -> Option { Slicable::set_as_slice(|out| runtime_support::read_storage(&twox_128(key)[..], out) == out.len()) } diff --git a/wasm-runtime/support/src/lib.rs b/wasm-runtime/support/src/lib.rs index b65b574351554..90c59a6e747c5 100644 --- a/wasm-runtime/support/src/lib.rs +++ b/wasm-runtime/support/src/lib.rs @@ -4,14 +4,22 @@ #![cfg_attr(feature = "strict", deny(warnings))] #![feature(alloc)] -//#[macro_use] extern crate alloc; -pub use alloc::vec::Vec; -pub use alloc::boxed::Box; -pub use alloc::rc::Rc; -pub use core::mem::{transmute, size_of, uninitialized, swap}; + +pub use alloc::vec; +pub use alloc::boxed; +pub use alloc::rc; +pub use core::mem; pub use core::slice; -pub use core::cell::{RefCell, Ref, RefMut}; +pub use core::cell; + +/// Common re-exports that are useful to have in scope. +pub mod prelude { + pub use alloc::vec::Vec; + pub use alloc::boxed::Box; +} + +use alloc::vec::Vec; extern crate pwasm_libc; extern crate pwasm_alloc; @@ -68,7 +76,7 @@ pub fn chain_id() -> u64 { /// Conduct a 256-bit Blake2 hash. pub fn blake2_256(data: &[u8]) -> [u8; 32] { unsafe { - let mut result: [u8; 32] = uninitialized(); + let mut result: [u8; 32] = Default::default(); // guaranteed to write into result. ext_blake2_256(&data[0], data.len() as u32, &mut result[0]); result @@ -78,7 +86,7 @@ pub fn blake2_256(data: &[u8]) -> [u8; 32] { /// Conduct four XX hashes to give a 256-bit result. pub fn twox_256(data: &[u8]) -> [u8; 32] { unsafe { - let mut result: [u8; 32] = uninitialized(); + let mut result: [u8; 32] = Default::default(); // guaranteed to write into result. ext_twox_256(&data[0], data.len() as u32, &mut result[0]); result @@ -88,7 +96,7 @@ pub fn twox_256(data: &[u8]) -> [u8; 32] { /// Conduct two XX hashes to give a 256-bit result. pub fn twox_128(data: &[u8]) -> [u8; 16] { unsafe { - let mut result: [u8; 16] = uninitialized(); + let mut result: [u8; 16] = Default::default(); // guaranteed to write into result. ext_twox_128(&data[0], data.len() as u32, &mut result[0]); result @@ -109,7 +117,7 @@ pub trait Printable { impl<'a> Printable for &'a [u8] { fn print(self) { unsafe { - ext_print(&self[0] as *const u8, self.len() as u32); + ext_print(self.as_ptr(), self.len() as u32); } } } @@ -132,7 +140,7 @@ macro_rules! impl_stubs { #[no_mangle] pub fn $name(input_data: *mut u8, input_len: usize) -> u64 { let input = unsafe { - $crate::Vec::from_raw_parts(input_data, input_len, input_len) + $crate::vec::Vec::from_raw_parts(input_data, input_len, input_len) }; let output = super::$name(input); diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 0aaa880e905df..c1051d34148a0 100644 Binary files a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm and b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm differ diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index cd47ef5fdbc7a..231fa8af919d6 100644 Binary files a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm and b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm differ diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 5c717847a5a2d..b1357890d880b 100644 Binary files a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm index 64fb6a48bfd6f..646b019bc0a08 100644 Binary files a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm differ