Files
pezkuwi-subxt/substrate/substrate/runtime-io/with_std.rs
T
Gav Wood bd066e27a6 Traitify Runtime (#104)
* Factor out safe-mix and dispatch

* Refactor dispatch into something more modular.

* Fix wasm build.

* Fix up timestamp

* fix warnings.

* Borked timestamp example

* Fix build

* Timestamp as skeleton for traity runtime.

* New storage macro.

* Dispatch module has traity API.

* Move consensus module to new API

* Refactoring and outer dispatch

* Avoid unnecessary derives.

* Abstract the low-level half of system.

* nicer outer dispatch syntax.

* Make runtime compile again (albeit in a heavily simplified state)

* Reworking runtime and the upper levels of system.

* Initial reworking of runtime:

- Introduced executive module;
- Introduced trait primitives module;
- Provided an API endpoint.

* Expose an additional function in system

* Another couple of functions traitified in executive.

* another function in executive traitified.

* One more function traitified.

* Finish traitifying executive!

* Traitify session module.

* Cleanups and ensure session gets run.

* First part of traitification of staking module.

* Bit more of staking traitified.

* Additional stuff in staking. Fix up session.

* Penultimate part of staking module.

* Final part of staking (code)

* Update demo runtime to include staking.

* Final tweaks for staking integration.

* Remove old runtime files.

* Schedule staking.

* Minor fixes

* First bits of democracy.

* Democracy module integrated.

* Fix warning.

* Traitify and integrate council module

* Council voting.

* Runtime binary and tweaks.

* Binary update.

* Fix `*Type` grumble.

* Fix up genesis_map

* Remove NonTrivialSlicable

* Staking "test externalities" stuff along with refactor.

* Add session test externalities constructor

* Fixed executor tests.

* Make one test in executive module work.

* Remove test framework stuff into common module.

* Enable other tests in executive

* Session tests reinstated, minor refactoring of keyring.

* Fix staking tests.

* Fix up democracy tests.

* First few tests in council.

* Council tests reinstated :)

* Avoid hardcoding blake2 into Header.

* Fix last few tests.

* Make all primitives generic.

* Fix tests.

* Refactor runtime to remove genesismap.

* Streamline runtime more with macrofied config.

* Clean paths

* Fix warning.

* Consolidate demo runtime crate.

* Remove stale code.

* Refactor away dodgy trait.

* Add corresponding Aux type.

* Fixes

* Rename Digesty -> Digest

* Rename Headery -> Header

* Blocky -> Block

* Fix wasm build.

* kill warnings

* more docs

* minor cleanups
2018-04-04 12:06:39 +02:00

198 lines
5.6 KiB
Rust

// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
#[macro_use]
extern crate environmental;
#[cfg_attr(test, macro_use)]
extern crate substrate_primitives as primitives;
extern crate substrate_state_machine;
extern crate triehash;
extern crate ed25519;
#[doc(hidden)]
pub extern crate substrate_codec as codec;
// re-export hashing functions.
pub use primitives::{blake2_256, twox_128, twox_256};
pub use substrate_state_machine::{Externalities, TestExternalities};
use primitives::hexdisplay::HexDisplay;
// TODO: use the real error, not NoError.
environmental!(ext: trait Externalities);
/// Get `key` from storage and return a `Vec`, empty if there's a problem.
pub fn storage(key: &[u8]) -> Option<Vec<u8>> {
ext::with(|ext| ext.storage(key).map(|s| s.to_vec()))
.expect("read_storage cannot be called outside of an Externalities-provided environment.")
}
/// 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 or None if the storage entry
/// doesn't exist at all.
pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option<usize> {
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[0..written].copy_from_slice(&value[0..written]);
value.len()
})).expect("read_storage cannot be called outside of an Externalities-provided environment.")
}
/// Set the storage of some particular key to Some value.
pub fn set_storage(key: &[u8], value: &[u8]) {
ext::with(|ext|
ext.set_storage(key.to_vec(), value.to_vec())
);
}
/// Clear the storage of some particular key.
pub fn clear_storage(key: &[u8]) {
ext::with(|ext|
ext.clear_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 get the resultant storage root.
pub fn storage_root() -> [u8; 32] {
ext::with(|ext|
ext.storage_root()
).unwrap_or([0u8; 32])
}
/// "Commit" all existing operations and get the resultant storage root.
pub fn enumerated_trie_root(serialised_values: &[&[u8]]) -> [u8; 32] {
triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0
}
/// Verify a ed25519 signature.
pub fn ed25519_verify<P: AsRef<[u8]>>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool {
ed25519::verify(sig, msg, pubkey)
}
/// Execute the given closure with global function available whose functionality routes into the
/// externalities `ext`. Forwards the value that the closure returns.
pub fn with_externalities<R, F: FnOnce() -> R>(ext: &mut Externalities, f: F) -> R {
ext::using(ext, f)
}
/// 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));
}
}
impl<'a> Printable for &'a str {
fn print(self) {
println!("Runtime: {}", self);
}
}
impl Printable for u64 {
fn print(self) {
println!("Runtime: {}", self);
}
}
/// Print a printable value.
pub fn print<T: Printable + Sized>(value: T) {
value.print();
}
#[macro_export]
macro_rules! impl_stubs {
( $( $new_name:ident $($nodecode:ident)* => $invoke: expr ),*) => {
/// Dispatch logic for the native runtime.
pub fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
match method {
$(
stringify!($new_name) => { impl_stubs!(@METHOD data $new_name $($nodecode)* => $invoke) }
)*
_ => None,
}
}
};
(@METHOD $data: ident $new_name: ident NO_DECODE => $invoke:expr) => {
Some($invoke($data))
};
(@METHOD $data: ident $new_name: ident => $invoke:expr) => {{
let mut data = $data;
let input = match $crate::codec::Slicable::decode(&mut data) {
Some(input) => input,
None => panic!("Bad input data provided to {}", stringify!($new_name)),
};
let output = $invoke(input);
Some($crate::codec::Slicable::encode(&output))
}}
}
#[cfg(test)]
mod std_tests {
use super::*;
#[test]
fn storage_works() {
let mut t = TestExternalities::new();
assert!(with_externalities(&mut t, || {
assert_eq!(storage(b"hello"), None);
set_storage(b"hello", b"world");
assert_eq!(storage(b"hello"), Some(b"world".to_vec()));
assert_eq!(storage(b"foo"), None);
set_storage(b"foo", &[1, 2, 3][..]);
true
}));
t = map![b"foo".to_vec() => b"bar".to_vec()];
assert!(!with_externalities(&mut t, || {
assert_eq!(storage(b"hello"), None);
assert_eq!(storage(b"foo"), Some(b"bar".to_vec()));
false
}));
}
#[test]
fn read_storage_works() {
let mut t: TestExternalities = map![
b":test".to_vec() => b"\x0b\0\0\0Hello world".to_vec()
];
with_externalities(&mut t, || {
let mut v = [0u8; 4];
assert!(read_storage(b":test", &mut v[..], 0).unwrap() >= 4);
assert_eq!(v, [11u8, 0, 0, 0]);
let mut w = [0u8; 11];
assert!(read_storage(b":test", &mut w[..], 4).unwrap() >= 11);
assert_eq!(&w, b"Hello world");
});
}
}