Phase 1 of repo reorg (#719)

* Remove unneeded script

* Rename Substrate Demo -> Substrate

* Rename demo -> node

* Build wasm from last rename.

* Merge ed25519 into substrate-primitives

* Minor tweak

* Rename substrate -> core

* Move substrate-runtime-support to core/runtime/support

* Rename/move substrate-runtime-version

* Move codec up a level

* Rename substrate-codec -> parity-codec

* Move environmental up a level

* Move pwasm-* up to top, ready for removal

* Remove requirement of s-r-support from s-r-primitives

* Move core/runtime/primitives into core/runtime-primitives

* Remove s-r-support dep from s-r-version

* Remove dep of s-r-support from bft

* Remove dep of s-r-support from node/consensus

* Sever all other core deps from s-r-support

* Forgot the no_std directive

* Rename non-SRML modules to sr-* to avoid match clashes

* Move runtime/* to srml/*

* Rename substrate-runtime-* -> srml-*

* Move srml to top-level
This commit is contained in:
Gav Wood
2018-09-12 11:13:31 +02:00
committed by Arkadiy Paronyan
parent 8fe5aa4c81
commit 1e01162505
374 changed files with 2845 additions and 2902 deletions
@@ -0,0 +1,106 @@
// 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/>.
#[cfg(feature = "std")]
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use H256;
/// An identifier for an authority in the consensus algorithm. The same size as ed25519::Public.
#[derive(Clone, Copy, PartialEq, Eq, Default, Encode, Decode)]
pub struct AuthorityId(pub [u8; 32]);
impl AuthorityId {
/// Create an id from a 32-byte slice. Panics with other lengths.
#[cfg(feature = "std")]
fn from_slice(data: &[u8]) -> Self {
let mut r = [0u8; 32];
r.copy_from_slice(data);
AuthorityId(r)
}
}
#[cfg(feature = "std")]
impl ::std::fmt::Display for AuthorityId {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", ::hexdisplay::HexDisplay::from(&self.0))
}
}
#[cfg(feature = "std")]
impl ::std::fmt::Debug for AuthorityId {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", ::hexdisplay::HexDisplay::from(&self.0))
}
}
#[cfg(feature = "std")]
impl ::std::hash::Hash for AuthorityId {
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl AsRef<[u8; 32]> for AuthorityId {
fn as_ref(&self) -> &[u8; 32] {
&self.0
}
}
impl AsRef<[u8]> for AuthorityId {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl Into<[u8; 32]> for AuthorityId {
fn into(self) -> [u8; 32] {
self.0
}
}
impl From<[u8; 32]> for AuthorityId {
fn from(a: [u8; 32]) -> Self {
AuthorityId(a)
}
}
impl AsRef<AuthorityId> for AuthorityId {
fn as_ref(&self) -> &AuthorityId {
&self
}
}
impl Into<H256> for AuthorityId {
fn into(self) -> H256 {
self.0.into()
}
}
#[cfg(feature = "std")]
impl Serialize for AuthorityId {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
::bytes::serialize(&self.0, serializer)
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for AuthorityId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
::bytes::deserialize_check_len(deserializer, ::bytes::ExpectedLen::Exact(32))
.map(|x| AuthorityId::from_slice(&x))
}
}
+158
View File
@@ -0,0 +1,158 @@
// 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/>.
//! Simple type for representing Vec<u8> with regards to serde.
use core::fmt;
use serde::{de, Serializer, Deserializer};
#[cfg(not(feature = "std"))]
mod alloc_types {
pub use ::alloc::string::String;
pub use ::alloc::vec::Vec;
}
#[cfg(feature = "std")]
mod alloc_types {
pub use ::std::vec::Vec;
pub use ::std::string::String;
}
pub use self::alloc_types::*;
/// Serializes a slice of bytes.
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
S: Serializer,
{
let hex: String = ::rustc_hex::ToHex::to_hex(bytes);
serializer.serialize_str(&format!("0x{}", hex))
}
/// Serialize a slice of bytes as uint.
///
/// The representation will have all leading zeros trimmed.
pub fn serialize_uint<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
S: Serializer,
{
let non_zero = bytes.iter().take_while(|b| **b == 0).count();
let bytes = &bytes[non_zero..];
if bytes.is_empty() {
return serializer.serialize_str("0x0");
}
let hex: String = ::rustc_hex::ToHex::to_hex(bytes);
let has_leading_zero = !hex.is_empty() && &hex[0..1] == "0";
serializer.serialize_str(
&format!("0x{}", if has_leading_zero { &hex[1..] } else { &hex })
)
}
/// Expected length of bytes vector.
#[derive(PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum ExpectedLen {
/// Any length in bytes.
#[cfg_attr(not(feature = "std"), allow(unused))]
Any,
/// Exact length in bytes.
Exact(usize),
/// A bytes length between (min; max].
Between(usize, usize),
}
impl fmt::Display for ExpectedLen {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
ExpectedLen::Any => write!(fmt, "even length"),
ExpectedLen::Exact(v) => write!(fmt, "length of {}", v * 2),
ExpectedLen::Between(min, max) => write!(fmt, "length between ({}; {}]", min * 2, max * 2),
}
}
}
/// Deserialize into vector of bytes.
#[cfg(feature = "std")]
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error> where
D: Deserializer<'de>,
{
deserialize_check_len(deserializer, ExpectedLen::Any)
}
/// Deserialize into vector of bytes with additional size check.
pub fn deserialize_check_len<'de, D>(deserializer: D, len: ExpectedLen) -> Result<Vec<u8>, D::Error> where
D: Deserializer<'de>,
{
struct Visitor {
len: ExpectedLen,
}
impl<'a> de::Visitor<'a> for Visitor {
type Value = Vec<u8>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a 0x-prefixed hex string with {}", self.len)
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
if v.len() < 2 || &v[0..2] != "0x" {
return Err(E::custom("prefix is missing"))
}
let is_len_valid = match self.len {
// just make sure that we have all nibbles
ExpectedLen::Any => v.len() % 2 == 0,
ExpectedLen::Exact(len) => v.len() == 2 * len + 2,
ExpectedLen::Between(min, max) => v.len() <= 2 * max + 2 && v.len() > 2 * min + 2,
};
if !is_len_valid {
return Err(E::invalid_length(v.len() - 2, &self))
}
let bytes = match self.len {
ExpectedLen::Between(..) if v.len() % 2 != 0 => {
::rustc_hex::FromHex::from_hex(&*format!("0{}", &v[2..]))
},
_ => ::rustc_hex::FromHex::from_hex(&v[2..])
};
#[cfg(feature = "std")]
fn format_err(e: ::rustc_hex::FromHexError) -> String {
format!("invalid hex value: {:?}", e)
}
#[cfg(not(feature = "std"))]
fn format_err(e: ::rustc_hex::FromHexError) -> String {
match e {
::rustc_hex::InvalidHexLength => format!("invalid hex value: invalid length"),
::rustc_hex::InvalidHexCharacter(c, p) =>
format!("invalid hex value: invalid character {} at position {}", c, p),
}
}
bytes.map_err(|e| E::custom(format_err(e)))
}
#[cfg(feature = "std")]
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
self.visit_str(&v)
}
}
// TODO [ToDr] Use raw bytes if we switch to RLP / binencoding
// (visit_bytes, visit_bytes_buf)
deserializer.deserialize_str(Visitor { len })
}
+352
View File
@@ -0,0 +1,352 @@
// 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/>.
// tag::description[]
//! Simple Ed25519 API.
// end::description[]
use untrusted;
use blake2_rfc;
use ring::{rand, signature};
use {hash::H512, AuthorityId};
use base58::{ToBase58, FromBase58};
/// Alias to 512-bit hash when used in the context of a signature on the relay chain.
pub type Signature = H512;
/// Length of the PKCS#8 encoding of the key.
pub const PKCS_LEN: usize = 85;
/// A localized signature also contains sender information.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct LocalizedSignature {
/// The signer of the signature.
pub signer: Public,
/// The signature itself.
pub signature: Signature,
}
/// Verify a message without type checking the parameters' types for the right size.
pub fn verify<P: AsRef<[u8]>>(sig: &[u8], message: &[u8], public: P) -> bool {
let public_key = untrusted::Input::from(public.as_ref());
let msg = untrusted::Input::from(message);
let sig = untrusted::Input::from(sig);
match signature::verify(&signature::ED25519, public_key, msg, sig) {
Ok(_) => true,
_ => false,
}
}
/// A public key.
#[derive(PartialEq, Eq, Clone)]
pub struct Public(pub [u8; 32]);
/// A key pair.
pub struct Pair(signature::Ed25519KeyPair);
impl ::std::hash::Hash for Public {
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
/// An error type for SS58 decoding.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum PublicError {
/// Bad alphabet.
BadBase58,
/// Bad length.
BadLength,
/// Unknown version.
UnknownVersion,
/// Invalid checksum.
InvalidChecksum,
}
impl Public {
/// A new instance from the given 32-byte `data`.
pub fn from_raw(data: [u8; 32]) -> Self {
Public(data)
}
/// A new instance from the given slice that should be 32 bytes long.
pub fn from_slice(data: &[u8]) -> Self {
let mut r = [0u8; 32];
r.copy_from_slice(data);
Public(r)
}
/// Some if the string is a properly encoded SS58Check address.
pub fn from_ss58check(s: &str) -> Result<Self, PublicError> {
let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding.
if d.len() != 35 {
// Invalid length.
return Err(PublicError::BadLength);
}
if d[0] != 42 {
// Invalid version.
return Err(PublicError::UnknownVersion);
}
if d[33..35] != blake2_rfc::blake2b::blake2b(64, &[], &d[0..33]).as_bytes()[0..2] {
// Invalid checksum.
return Err(PublicError::InvalidChecksum);
}
Ok(Self::from_slice(&d[1..33]))
}
/// Return a `Vec<u8>` filled with raw data.
pub fn to_raw_vec(self) -> Vec<u8> {
let r: &[u8; 32] = self.as_ref();
r.to_vec()
}
/// Return a slice filled with raw data.
pub fn as_slice(&self) -> &[u8] {
let r: &[u8; 32] = self.as_ref();
&r[..]
}
/// Return a slice filled with raw data.
pub fn as_array_ref(&self) -> &[u8; 32] {
self.as_ref()
}
/// Return the ss58-check string for this key.
pub fn to_ss58check(&self) -> String {
let mut v = vec![42u8];
v.extend(self.as_slice());
let r = blake2_rfc::blake2b::blake2b(64, &[], &v);
v.extend(&r.as_bytes()[0..2]);
v.to_base58()
}
}
impl AsRef<[u8; 32]> for Public {
fn as_ref(&self) -> &[u8; 32] {
&self.0
}
}
impl AsRef<[u8]> for Public {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl Into<[u8; 32]> for Public {
fn into(self) -> [u8; 32] {
self.0
}
}
impl AsRef<Public> for Public {
fn as_ref(&self) -> &Public {
&self
}
}
impl AsRef<Pair> for Pair {
fn as_ref(&self) -> &Pair {
&self
}
}
impl Into<AuthorityId> for Public {
fn into(self) -> AuthorityId {
AuthorityId(self.0)
}
}
impl From<AuthorityId> for Public {
fn from(id: AuthorityId) -> Self {
Public(id.0)
}
}
impl ::std::fmt::Display for Public {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", self.to_ss58check())
}
}
impl ::std::fmt::Debug for Public {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
let s = self.to_ss58check();
write!(f, "{} ({}...)", ::hexdisplay::HexDisplay::from(&self.0), &s[0..8])
}
}
impl Pair {
/// Generate new secure (random) key pair, yielding it and the corresponding pkcs#8 bytes.
pub fn generate_with_pkcs8() -> (Self, [u8; PKCS_LEN]) {
let rng = rand::SystemRandom::new();
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).expect("system randomness is available; qed");
let pair = Self::from_pkcs8(&pkcs8_bytes).expect("just-generated pkcs#8 data is valid; qed");
(pair, pkcs8_bytes)
}
/// Generate new secure (random) key pair.
pub fn generate() -> Pair {
let (pair, _) = Self::generate_with_pkcs8();
pair
}
/// Generate from pkcs#8 bytes.
pub fn from_pkcs8(pkcs8_bytes: &[u8]) -> Result<Self, ::ring::error::Unspecified> {
signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).map(Pair)
}
/// Make a new key pair from a seed phrase.
/// NOTE: prefer pkcs#8 unless security doesn't matter -- this is used primarily for tests.
pub fn from_seed(seed: &[u8; 32]) -> Pair {
let key = signature::Ed25519KeyPair::from_seed_unchecked(untrusted::Input::from(&seed[..]))
.expect("seed has valid length; qed");
Pair(key)
}
/// Sign a message.
pub fn sign(&self, message: &[u8]) -> Signature {
let mut r = [0u8; 64];
r.copy_from_slice(self.0.sign(message).as_ref());
Signature::from(r)
}
/// Get the public key.
pub fn public(&self) -> Public {
let mut r = [0u8; 32];
let pk = self.0.public_key_bytes();
r.copy_from_slice(pk);
Public(r)
}
/// Derive a child key. Probably unsafe and broken.
// TODO: proper HD derivation https://cardanolaunch.com/assets/Ed25519_BIP.pdf
pub fn derive_child_probably_bad(&self, chain_data: &[u8]) -> Pair {
let sig = self.sign(chain_data);
let mut seed = [0u8; 32];
seed.copy_from_slice(&sig.0[..32]);
Pair::from_seed(&seed)
}
}
/// Verify a signature on a message.
pub fn verify_strong<P: AsRef<Public>>(sig: &Signature, message: &[u8], pubkey: P) -> bool {
let public_key = untrusted::Input::from(&pubkey.as_ref().0[..]);
let msg = untrusted::Input::from(message);
let sig = untrusted::Input::from(&sig.0[..]);
match signature::verify(&signature::ED25519, public_key, msg, sig) {
Ok(_) => true,
_ => false,
}
}
/// Something that acts as a signature allowing a message to be verified.
pub trait Verifiable {
/// Verify something that acts like a signature.
fn verify<P: AsRef<Public>>(&self, message: &[u8], pubkey: P) -> bool;
}
impl Verifiable for Signature {
/// Verify something that acts like a signature.
fn verify<P: AsRef<Public>>(&self, message: &[u8], pubkey: P) -> bool {
verify_strong(&self, message, pubkey)
}
}
impl Verifiable for LocalizedSignature {
fn verify<P: AsRef<Public>>(&self, message: &[u8], pubkey: P) -> bool {
pubkey.as_ref() == &self.signer && self.signature.verify(message, pubkey)
}
}
#[cfg(test)]
mod test {
use super::*;
fn _test_primitives_signature_and_local_the_same() {
fn takes_two<T>(_: T, _: T) { }
takes_two(Signature::default(), ::Signature::default())
}
#[test]
fn test_vector_should_work() {
let pair: Pair = Pair::from_seed(&hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"));
let public = pair.public();
assert_eq!(public, Public::from_raw(hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a")));
let message = b"";
let signature: Signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b").into();
assert!(&pair.sign(&message[..]) == &signature);
assert!(verify_strong(&signature, &message[..], &public));
}
#[test]
fn generated_pair_should_work() {
let pair = Pair::generate();
let public = pair.public();
let message = b"Something important";
let signature = pair.sign(&message[..]);
assert!(verify_strong(&signature, &message[..], &public));
}
#[test]
fn seeded_pair_should_work() {
use ::hexdisplay::HexDisplay;
let pair = Pair::from_seed(b"12345678901234567890123456789012");
let public = pair.public();
assert_eq!(public, Public::from_raw(hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee")));
let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000");
let signature = pair.sign(&message[..]);
println!("Correct signature: {}", HexDisplay::from(&signature.0));
assert!(verify_strong(&signature, &message[..], &public));
}
#[test]
fn generate_with_pkcs8_recovery_possible() {
let (pair1, pkcs8) = Pair::generate_with_pkcs8();
let pair2 = Pair::from_pkcs8(&pkcs8).unwrap();
assert_eq!(pair1.public(), pair2.public());
}
#[test]
fn derive_child() {
let pair = Pair::generate();
let _pair2 = pair.derive_child_probably_bad(b"session_1234");
}
#[test]
fn ss58check_roundtrip_works() {
let pair = Pair::from_seed(b"12345678901234567890123456789012");
let public = pair.public();
let s = public.to_ss58check();
println!("Correct: {}", s);
let cmp = Public::from_ss58check(&s).unwrap();
assert_eq!(cmp, public);
}
#[test]
fn ss58check_known_works() {
let k = "5CGavy93sZgPPjHyziRohwVumxiHXMGmQLyuqQP4ZFx5vRU9";
let enc = hex!["090fa15cb5b1666222fff584b4cc2b1761fe1e238346b340491b37e25ea183ff"];
assert_eq!(Public::from_ss58check(k).unwrap(), Public::from_raw(enc));
}
}
+166
View File
@@ -0,0 +1,166 @@
// 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/>.
//! A fixed hash type.
#[cfg(feature = "std")]
use serde::{Serialize, Serializer, Deserialize, Deserializer};
#[cfg(feature = "std")]
use bytes;
#[cfg(feature = "std")]
use core::cmp;
#[cfg(feature = "std")]
use rlp::{Rlp, RlpStream, DecoderError};
macro_rules! impl_rest {
($name: ident, $len: expr) => {
#[cfg(feature = "std")]
impl Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
bytes::serialize(&self.0, serializer)
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Exact($len))
.map(|x| (&*x).into())
}
}
impl ::codec::Encode for $name {
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.0.using_encoded(f)
}
}
impl ::codec::Decode for $name {
fn decode<I: ::codec::Input>(input: &mut I) -> Option<Self> {
<[u8; $len] as ::codec::Decode>::decode(input).map($name)
}
}
#[cfg(feature = "std")]
impl ::rlp::Encodable for $name {
fn rlp_append(&self, s: &mut RlpStream) {
s.encoder().encode_value(self);
}
}
#[cfg(feature = "std")]
impl ::rlp::Decodable for $name {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder().decode_value(|bytes| match bytes.len().cmp(&$len) {
cmp::Ordering::Less => Err(DecoderError::RlpIsTooShort),
cmp::Ordering::Greater => Err(DecoderError::RlpIsTooBig),
cmp::Ordering::Equal => {
let mut t = [0u8; $len];
t.copy_from_slice(bytes);
Ok($name(t))
}
})
}
}
}
}
construct_hash!(H160, 20);
construct_hash!(H256, 32);
construct_hash!(H512, 64);
impl_rest!(H160, 20);
impl_rest!(H256, 32);
impl_rest!(H512, 64);
#[cfg(test)]
mod tests {
use super::*;
use substrate_serializer as ser;
use rlp::{Encodable, RlpStream};
#[test]
fn test_hash_is_encodable() {
let h = H160::from(21);
let mut s = RlpStream::new();
h.rlp_append(&mut s);
assert_eq!(s.drain().into_vec(), &[148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21]);
}
#[test]
fn test_hash_is_decodable() {
let data = vec![148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123];
let res = ::rlp::decode::<H160>(&data);
assert!(res.is_ok());
assert_eq!(res.unwrap(), H160::from(123));
let res = ::rlp::decode::<H256>(&data);
assert!(res.is_err());
}
#[test]
fn test_h160() {
let tests = vec![
(Default::default(), "0x0000000000000000000000000000000000000000"),
(H160::from(2), "0x0000000000000000000000000000000000000002"),
(H160::from(15), "0x000000000000000000000000000000000000000f"),
(H160::from(16), "0x0000000000000000000000000000000000000010"),
(H160::from(1_000), "0x00000000000000000000000000000000000003e8"),
(H160::from(100_000), "0x00000000000000000000000000000000000186a0"),
(H160::from(u64::max_value()), "0x000000000000000000000000ffffffffffffffff"),
];
for (number, expected) in tests {
assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number));
assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap());
}
}
#[test]
fn test_h256() {
let tests = vec![
(Default::default(), "0x0000000000000000000000000000000000000000000000000000000000000000"),
(H256::from(2), "0x0000000000000000000000000000000000000000000000000000000000000002"),
(H256::from(15), "0x000000000000000000000000000000000000000000000000000000000000000f"),
(H256::from(16), "0x0000000000000000000000000000000000000000000000000000000000000010"),
(H256::from(1_000), "0x00000000000000000000000000000000000000000000000000000000000003e8"),
(H256::from(100_000), "0x00000000000000000000000000000000000000000000000000000000000186a0"),
(H256::from(u64::max_value()), "0x000000000000000000000000000000000000000000000000ffffffffffffffff"),
];
for (number, expected) in tests {
assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number));
assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap());
}
}
#[test]
fn test_invalid() {
assert!(ser::from_str::<H256>("\"0x000000000000000000000000000000000000000000000000000000000000000\"").unwrap_err().is_data());
assert!(ser::from_str::<H256>("\"0x000000000000000000000000000000000000000000000000000000000000000g\"").unwrap_err().is_data());
assert!(ser::from_str::<H256>("\"0x00000000000000000000000000000000000000000000000000000000000000000\"").unwrap_err().is_data());
assert!(ser::from_str::<H256>("\"\"").unwrap_err().is_data());
assert!(ser::from_str::<H256>("\"0\"").unwrap_err().is_data());
assert!(ser::from_str::<H256>("\"10\"").unwrap_err().is_data());
}
#[test]
fn test_heapsizeof() {
use heapsize::HeapSizeOf;
let h = H256::new();
assert_eq!(h.heap_size_of_children(), 0);
}
}
+53
View File
@@ -0,0 +1,53 @@
// Copyright 2018 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/>.
//! Polkadot Blake2b Hasher implementation
use hashdb::Hasher;
use plain_hasher::PlainHasher;
use hash::H256;
pub mod blake2 {
use super::{Hasher, PlainHasher, H256};
#[cfg(feature = "std")]
use hashing::blake2_256;
#[cfg(not(feature = "std"))]
extern "C" {
fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8);
}
#[cfg(not(feature = "std"))]
fn blake2_256(data: &[u8]) -> [u8; 32] {
let mut result: [u8; 32] = Default::default();
unsafe {
ext_blake2_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr());
}
result
}
/// Concrete implementation of Hasher using Blake2b 256-bit hashes
#[derive(Debug)]
pub struct Blake2Hasher;
impl Hasher for Blake2Hasher {
type Out = H256;
type StdHasher = PlainHasher;
const LENGTH:usize = 32;
fn hash(x: &[u8]) -> Self::Out {
blake2_256(x).into()
}
}
}
+106
View File
@@ -0,0 +1,106 @@
// 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/>.
//! Hashing functions.
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]) {
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 = [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]) {
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 = [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]) {
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 = [0; 16];
blake2_128_into(data, &mut r);
r
}
/// Do a XX 128-bit hash and place result in `dest`.
pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) {
use ::core::hash::Hasher;
let mut h0 = twox_hash::XxHash::with_seed(0);
let mut h1 = twox_hash::XxHash::with_seed(1);
h0.write(data);
h1.write(data);
let r0 = h0.finish();
let r1 = h1.finish();
use byteorder::{ByteOrder, LittleEndian};
LittleEndian::write_u64(&mut dest[0..8], r0);
LittleEndian::write_u64(&mut dest[8..16], r1);
}
/// Do a XX 128-bit hash and return result.
pub fn twox_128(data: &[u8]) -> [u8; 16] {
let mut r: [u8; 16] = [0; 16];
twox_128_into(data, &mut r);
r
}
/// Do a XX 256-bit hash and place result in `dest`.
pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) {
use ::core::hash::Hasher;
use byteorder::{ByteOrder, LittleEndian};
let mut h0 = twox_hash::XxHash::with_seed(0);
let mut h1 = twox_hash::XxHash::with_seed(1);
let mut h2 = twox_hash::XxHash::with_seed(2);
let mut h3 = twox_hash::XxHash::with_seed(3);
h0.write(data);
h1.write(data);
h2.write(data);
h3.write(data);
let r0 = h0.finish();
let r1 = h1.finish();
let r2 = h2.finish();
let r3 = h3.finish();
LittleEndian::write_u64(&mut dest[0..8], r0);
LittleEndian::write_u64(&mut dest[8..16], r1);
LittleEndian::write_u64(&mut dest[16..24], r2);
LittleEndian::write_u64(&mut dest[24..32], r3);
}
/// Do a XX 256-bit hash and return result.
pub fn twox_256(data: &[u8]) -> [u8; 32] {
let mut r: [u8; 32] = [0; 32];
twox_256_into(data, &mut r);
r
}
@@ -0,0 +1,94 @@
// 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/>.
//! Wrapper type for byte collections that outputs hex.
/// Simple wrapper to display hex representation of bytes.
pub struct HexDisplay<'a>(&'a [u8]);
impl<'a> HexDisplay<'a> {
/// Create new instance that will display `d` as a hex string when displayed.
pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) }
}
impl<'a> ::core::fmt::Display for HexDisplay<'a> {
fn fmt(&self, fmtr: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
if self.0.len() < 1027 {
for byte in self.0 {
fmtr.write_fmt(format_args!("{:02x}", byte))?;
}
} else {
for byte in &self.0[0..512] {
fmtr.write_fmt(format_args!("{:02x}", byte))?;
}
fmtr.write_str("...")?;
for byte in &self.0[self.0.len() - 512..] {
fmtr.write_fmt(format_args!("{:02x}", byte))?;
}
}
Ok(())
}
}
/// Simple trait to transform various types to `&[u8]`
pub trait AsBytesRef {
/// Transform `self` into `&[u8]`.
fn as_bytes_ref(&self) -> &[u8];
}
impl<'a> AsBytesRef for &'a [u8] {
fn as_bytes_ref(&self) -> &[u8] { self }
}
impl AsBytesRef for [u8] {
fn as_bytes_ref(&self) -> &[u8] { &self }
}
impl AsBytesRef for ::bytes::Vec<u8> {
fn as_bytes_ref(&self) -> &[u8] { &self }
}
macro_rules! impl_non_endians {
( $( $t:ty ),* ) => { $(
impl AsBytesRef for $t {
fn as_bytes_ref(&self) -> &[u8] { &self[..] }
}
)* }
}
impl_non_endians!([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]);
/// Format into ASCII + # + hex, suitable for storage key preimages.
pub fn ascii_format(asciish: &[u8]) -> String {
let mut r = String::new();
let mut latch = false;
for c in asciish {
match (latch, *c) {
(false, 32...127) => r.push(*c as char),
_ => {
if !latch {
r.push('#');
latch = true;
}
r.push_str(&format!("{:02x}", *c));
}
}
}
r
}
+145
View File
@@ -0,0 +1,145 @@
// 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/>.
// tag::description[]
//! Shareable Polkadot types.
// end::description[]
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
#[macro_use]
extern crate crunchy;
#[macro_use]
extern crate fixed_hash;
#[macro_use]
extern crate uint as uint_crate;
#[macro_use]
extern crate parity_codec_derive;
extern crate rustc_hex;
extern crate byteorder;
extern crate parity_codec as codec;
#[cfg(feature = "std")]
extern crate rlp;
#[cfg(feature = "std")]
extern crate serde;
#[cfg(feature = "std")]
extern crate twox_hash;
#[cfg(feature = "std")]
extern crate blake2_rfc;
#[cfg(feature = "std")]
extern crate ring;
#[cfg(feature = "std")]
extern crate base58;
#[cfg(feature = "std")]
extern crate untrusted;
#[cfg(test)]
#[macro_use]
extern crate hex_literal;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "std")]
extern crate core;
#[cfg(feature = "std")]
extern crate wasmi;
extern crate hashdb;
extern crate plain_hasher;
#[cfg(feature = "std")]
extern crate patricia_trie;
#[cfg(feature = "std")]
extern crate elastic_array;
extern crate sr_std as rstd;
#[cfg(test)]
extern crate substrate_serializer;
#[cfg(test)]
extern crate heapsize;
#[cfg(test)]
#[macro_use]
extern crate pretty_assertions;
#[macro_export]
macro_rules! map {
($( $name:expr => $value:expr ),*) => (
vec![ $( ( $name, $value ) ),* ].into_iter().collect()
)
}
use rstd::prelude::*;
use rstd::ops::Deref;
#[cfg(feature = "std")]
pub mod bytes;
#[cfg(feature = "std")]
pub mod hashing;
#[cfg(feature = "std")]
pub use hashing::{blake2_256, twox_128, twox_256};
#[cfg(feature = "std")]
pub mod hexdisplay;
#[cfg(feature = "std")]
pub mod ed25519;
pub mod u32_trait;
pub mod hash;
mod hasher;
pub mod sandbox;
pub mod storage;
pub mod uint;
mod authority_id;
#[cfg(feature = "std")]
mod rlp_codec;
#[cfg(test)]
mod tests;
pub use self::hash::{H160, H256, H512};
pub use self::uint::U256;
pub use authority_id::AuthorityId;
// Switch back to Blake after PoC-3 is out
// pub use self::hasher::blake::BlakeHasher;
pub use self::hasher::blake2::Blake2Hasher;
#[cfg(feature = "std")]
pub use self::rlp_codec::RlpCodec;
/// A 512-bit value interpreted as a signature.
pub type Signature = hash::H512;
/// Hex-serialised shim for `Vec<u8>`.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord))]
pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl From<Vec<u8>> for Bytes {
fn from(s: Vec<u8>) -> Self { Bytes(s) }
}
impl Deref for Bytes {
type Target = [u8];
fn deref(&self) -> &[u8] { &self.0[..] }
}
+123
View File
@@ -0,0 +1,123 @@
// Copyright 2018 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/>.
//! Polkadot Blake2b (trie) NodeCodec implementation
use elastic_array::{ElasticArray1024, ElasticArray128};
use hashdb::Hasher;
use rlp::{DecoderError, RlpStream, Rlp, Prototype};
use core::marker::PhantomData;
use patricia_trie::{NibbleSlice, NodeCodec, node::Node, ChildReference};
use hash::H256;
use Blake2Hasher;
/// Concrete implementation of a `NodeCodec` with Rlp encoding, generic over the `Hasher`
pub struct RlpNodeCodec<H: Hasher> {mark: PhantomData<H>}
/// Convenience type for a Blake2_256/Rlp flavoured NodeCodec
pub type RlpCodec = RlpNodeCodec<Blake2Hasher>;
impl NodeCodec<Blake2Hasher> for RlpCodec {
type Error = DecoderError;
const HASHED_NULL_NODE : H256 = H256( [0x45, 0xb0, 0xcf, 0xc2, 0x20, 0xce, 0xec, 0x5b, 0x7c, 0x1c, 0x62, 0xc4, 0xd4, 0x19, 0x3d, 0x38, 0xe4, 0xeb, 0xa4, 0x8e, 0x88, 0x15, 0x72, 0x9c, 0xe7, 0x5f, 0x9c, 0xa, 0xb0, 0xe4, 0xc1, 0xc0] );
fn decode(data: &[u8]) -> ::std::result::Result<Node, Self::Error> {
let r = Rlp::new(data);
match r.prototype()? {
// either leaf or extension - decode first item with NibbleSlice::???
// and use is_leaf return to figure out which.
// if leaf, second item is a value (is_data())
// if extension, second item is a node (either SHA3 to be looked up and
// fed back into this function or inline RLP which can be fed back into this function).
Prototype::List(2) => match NibbleSlice::from_encoded(r.at(0)?.data()?) {
(slice, true) => Ok(Node::Leaf(slice, r.at(1)?.data()?)),
(slice, false) => Ok(Node::Extension(slice, r.at(1)?.as_raw())),
},
// branch - first 16 are nodes, 17th is a value (or empty).
Prototype::List(17) => {
let mut nodes = [&[] as &[u8]; 16];
for i in 0..16 {
nodes[i] = r.at(i)?.as_raw();
}
Ok(Node::Branch(nodes, if r.at(16)?.is_empty() { None } else { Some(r.at(16)?.data()?) }))
},
// an empty branch index.
Prototype::Data(0) => Ok(Node::Empty),
// something went wrong.
_ => Err(DecoderError::Custom("Rlp is not valid."))
}
}
fn try_decode_hash(data: &[u8]) -> Option<<Blake2Hasher as Hasher>::Out> {
let r = Rlp::new(data);
if r.is_data() && r.size() == Blake2Hasher::LENGTH {
Some(r.as_val().expect("Hash is the correct size; qed"))
} else {
None
}
}
fn is_empty_node(data: &[u8]) -> bool {
Rlp::new(data).is_empty()
}
fn empty_node() -> ElasticArray1024<u8> {
let mut stream = RlpStream::new();
stream.append_empty_data();
stream.drain()
}
fn leaf_node(partial: &[u8], value: &[u8]) -> ElasticArray1024<u8> {
let mut stream = RlpStream::new_list(2);
stream.append(&partial);
stream.append(&value);
stream.drain()
}
fn ext_node(partial: &[u8], child_ref: ChildReference<<Blake2Hasher as Hasher>::Out>) -> ElasticArray1024<u8> {
let mut stream = RlpStream::new_list(2);
stream.append(&partial);
match child_ref {
ChildReference::Hash(h) => stream.append(&h),
ChildReference::Inline(inline_data, len) => {
let bytes = &AsRef::<[u8]>::as_ref(&inline_data)[..len];
stream.append_raw(bytes, 1)
},
};
stream.drain()
}
fn branch_node<I>(children: I, value: Option<ElasticArray128<u8>>) -> ElasticArray1024<u8>
where I: IntoIterator<Item=Option<ChildReference<<Blake2Hasher as Hasher>::Out>>>
{
let mut stream = RlpStream::new_list(17);
for child_ref in children {
match child_ref {
Some(c) => match c {
ChildReference::Hash(h) => stream.append(&h),
ChildReference::Inline(inline_data, len) => {
let bytes = &AsRef::<[u8]>::as_ref(&inline_data)[..len];
stream.append_raw(bytes, 1)
},
},
None => stream.append_empty_data()
};
}
if let Some(value) = value {
stream.append(&&*value);
} else {
stream.append_empty_data();
}
stream.drain()
}
}
+221
View File
@@ -0,0 +1,221 @@
// Copyright 2018 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/>.
//! Definition of a sandbox environment.
#[cfg(test)]
use codec::Encode;
use rstd::vec::Vec;
/// Error error that can be returned from host function.
#[derive(Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct HostError;
/// Representation of a typed wasm value.
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum TypedValue {
/// Value of 32-bit signed or unsigned integer.
#[codec(index = "1")]
I32(i32),
/// Value of 64-bit signed or unsigned integer.
#[codec(index = "2")]
I64(i64),
/// Value of 32-bit IEEE 754-2008 floating point number represented as a bit pattern.
#[codec(index = "3")]
F32(i32),
/// Value of 64-bit IEEE 754-2008 floating point number represented as a bit pattern.
#[codec(index = "4")]
F64(i64),
}
impl TypedValue {
/// Returns `Some` if this value of type `I32`.
pub fn as_i32(&self) -> Option<i32> {
match *self {
TypedValue::I32(v) => Some(v),
_ => None,
}
}
}
#[cfg(feature = "std")]
impl From<::wasmi::RuntimeValue> for TypedValue {
fn from(val: ::wasmi::RuntimeValue) -> TypedValue {
use ::wasmi::RuntimeValue;
match val {
RuntimeValue::I32(v) => TypedValue::I32(v),
RuntimeValue::I64(v) => TypedValue::I64(v),
RuntimeValue::F32(v) => TypedValue::F32(v.to_bits() as i32),
RuntimeValue::F64(v) => TypedValue::F64(v.to_bits() as i64),
}
}
}
#[cfg(feature = "std")]
impl From<TypedValue> for ::wasmi::RuntimeValue {
fn from(val: TypedValue) -> ::wasmi::RuntimeValue {
use ::wasmi::RuntimeValue;
use ::wasmi::nan_preserving_float::{F32, F64};
match val {
TypedValue::I32(v) => RuntimeValue::I32(v),
TypedValue::I64(v) => RuntimeValue::I64(v),
TypedValue::F32(v_bits) => RuntimeValue::F32(F32::from_bits(v_bits as u32)),
TypedValue::F64(v_bits) => RuntimeValue::F64(F64::from_bits(v_bits as u64)),
}
}
}
/// Typed value that can be returned from a function.
///
/// Basically a `TypedValue` plus `Unit`, for functions which return nothing.
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum ReturnValue {
/// For returning nothing.
Unit,
/// For returning some concrete value.
Value(TypedValue),
}
impl From<TypedValue> for ReturnValue {
fn from(v: TypedValue) -> ReturnValue {
ReturnValue::Value(v)
}
}
impl ReturnValue {
/// Maximum number of bytes `ReturnValue` might occupy when serialized with
/// `Codec`.
///
/// Breakdown:
/// 1 byte for encoding unit/value variant
/// 1 byte for encoding value type
/// 8 bytes for encoding the biggest value types available in wasm: f64, i64.
pub const ENCODED_MAX_SIZE: usize = 10;
}
#[test]
fn return_value_encoded_max_size() {
let encoded = ReturnValue::Value(TypedValue::I64(-1)).encode();
assert_eq!(encoded.len(), ReturnValue::ENCODED_MAX_SIZE);
}
/// Describes an entity to define or import into the environment.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum ExternEntity {
/// Function that is specified by an index in a default table of
/// a module that creates the sandbox.
#[codec(index = "1")]
Function(u32),
/// Linear memory that is specified by some identifier returned by sandbox
/// module upon creation new sandboxed memory.
#[codec(index = "2")]
Memory(u32),
}
/// An entry in a environment definition table.
///
/// Each entry has a two-level name and description of an entity
/// being defined.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct Entry {
/// Module name of which corresponding entity being defined.
pub module_name: Vec<u8>,
/// Field name in which corresponding entity being defined.
pub field_name: Vec<u8>,
/// External entity being defined.
pub entity: ExternEntity,
}
/// Definition of runtime that could be used by sandboxed code.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct EnvironmentDefinition {
/// Vector of all entries in the environment definition.
pub entries: Vec<Entry>,
}
/// Constant for specifying no limit when creating a sandboxed
/// memory instance. For FFI purposes.
pub const MEM_UNLIMITED: u32 = -1i32 as u32;
/// No error happened.
///
/// For FFI purposes.
pub const ERR_OK: u32 = 0;
/// Validation or instantiation error occured when creating new
/// sandboxed module instance.
///
/// For FFI purposes.
pub const ERR_MODULE: u32 = -1i32 as u32;
/// Out-of-bounds access attempted with memory or table.
///
/// For FFI purposes.
pub const ERR_OUT_OF_BOUNDS: u32 = -2i32 as u32;
/// Execution error occurred (typically trap).
///
/// For FFI purposes.
pub const ERR_EXECUTION: u32 = -3i32 as u32;
#[cfg(test)]
mod tests {
use super::*;
use std::fmt;
use codec::Codec;
fn roundtrip<S: Codec + PartialEq + fmt::Debug>(s: S) {
let encoded = s.encode();
assert_eq!(S::decode(&mut &encoded[..]).unwrap(), s);
}
#[test]
fn env_def_roundtrip() {
roundtrip(EnvironmentDefinition {
entries: vec![],
});
roundtrip(EnvironmentDefinition {
entries: vec![
Entry {
module_name: b"kernel"[..].into(),
field_name: b"memory"[..].into(),
entity: ExternEntity::Memory(1337),
},
],
});
roundtrip(EnvironmentDefinition {
entries: vec![
Entry {
module_name: b"env"[..].into(),
field_name: b"abort"[..].into(),
entity: ExternEntity::Function(228),
},
],
});
}
}
+44
View File
@@ -0,0 +1,44 @@
// 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/>.
//! Contract execution data.
#[cfg(feature = "std")]
use bytes;
use rstd::vec::Vec;
/// Contract storage key.
#[derive(PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))]
pub struct StorageKey(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Contract storage entry data.
#[derive(PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))]
pub struct StorageData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Storage change set
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, PartialEq, Eq))]
pub struct StorageChangeSet<Hash> {
/// Block hash
pub block: Hash,
/// A list of changes
pub changes: Vec<(
StorageKey,
Option<StorageData>,
)>,
}
+17
View File
@@ -0,0 +1,17 @@
// 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/>.
//! Tests.
@@ -0,0 +1,89 @@
// 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/>.
//! An u32 trait with "values" as impl'd types.
/// A u32 value, wrapped in a trait because we don't yet have const generics.
pub trait Value {
/// The actual value represented by the impl'ing type.
const VALUE: u32;
}
/// Type representing the value 0 for the `Value` trait.
pub struct _0; impl Value for _0 { const VALUE: u32 = 0; }
/// Type representing the value 1 for the `Value` trait.
pub struct _1; impl Value for _1 { const VALUE: u32 = 1; }
/// Type representing the value 2 for the `Value` trait.
pub struct _2; impl Value for _2 { const VALUE: u32 = 2; }
/// Type representing the value 3 for the `Value` trait.
pub struct _3; impl Value for _3 { const VALUE: u32 = 3; }
/// Type representing the value 4 for the `Value` trait.
pub struct _4; impl Value for _4 { const VALUE: u32 = 4; }
/// Type representing the value 5 for the `Value` trait.
pub struct _5; impl Value for _5 { const VALUE: u32 = 5; }
/// Type representing the value 6 for the `Value` trait.
pub struct _6; impl Value for _6 { const VALUE: u32 = 6; }
/// Type representing the value 7 for the `Value` trait.
pub struct _7; impl Value for _7 { const VALUE: u32 = 7; }
/// Type representing the value 8 for the `Value` trait.
pub struct _8; impl Value for _8 { const VALUE: u32 = 8; }
/// Type representing the value 9 for the `Value` trait.
pub struct _9; impl Value for _9 { const VALUE: u32 = 9; }
/// Type representing the value 10 for the `Value` trait.
pub struct _10; impl Value for _10 { const VALUE: u32 = 10; }
/// Type representing the value 11 for the `Value` trait.
pub struct _11; impl Value for _11 { const VALUE: u32 = 11; }
/// Type representing the value 12 for the `Value` trait.
pub struct _12; impl Value for _12 { const VALUE: u32 = 12; }
/// Type representing the value 13 for the `Value` trait.
pub struct _13; impl Value for _13 { const VALUE: u32 = 13; }
/// Type representing the value 14 for the `Value` trait.
pub struct _14; impl Value for _14 { const VALUE: u32 = 14; }
/// Type representing the value 15 for the `Value` trait.
pub struct _15; impl Value for _15 { const VALUE: u32 = 15; }
/// Type representing the value 16 for the `Value` trait.
pub struct _16; impl Value for _16 { const VALUE: u32 = 16; }
/// Type representing the value 24 for the `Value` trait.
pub struct _24; impl Value for _24 { const VALUE: u32 = 24; }
/// Type representing the value 32 for the `Value` trait.
pub struct _32; impl Value for _32 { const VALUE: u32 = 32; }
/// Type representing the value 40 for the `Value` trait.
pub struct _40; impl Value for _40 { const VALUE: u32 = 40; }
/// Type representing the value 48 for the `Value` trait.
pub struct _48; impl Value for _48 { const VALUE: u32 = 48; }
/// Type representing the value 56 for the `Value` trait.
pub struct _56; impl Value for _56 { const VALUE: u32 = 56; }
/// Type representing the value 64 for the `Value` trait.
pub struct _64; impl Value for _64 { const VALUE: u32 = 64; }
/// Type representing the value 80 for the `Value` trait.
pub struct _80; impl Value for _80 { const VALUE: u32 = 80; }
/// Type representing the value 96 for the `Value` trait.
pub struct _96; impl Value for _96 { const VALUE: u32 = 96; }
/// Type representing the value 112 for the `Value` trait.
pub struct _112; impl Value for _112 { const VALUE: u32 = 112; }
/// Type representing the value 128 for the `Value` trait.
pub struct _128; impl Value for _128 { const VALUE: u32 = 128; }
/// Type representing the value 160 for the `Value` trait.
pub struct _160; impl Value for _160 { const VALUE: u32 = 160; }
/// Type representing the value 192 for the `Value` trait.
pub struct _192; impl Value for _192 { const VALUE: u32 = 192; }
/// Type representing the value 224 for the `Value` trait.
pub struct _224; impl Value for _224 { const VALUE: u32 = 224; }
/// Type representing the value 256 for the `Value` trait.
pub struct _256; impl Value for _256 { const VALUE: u32 = 256; }
/// Type representing the value 384 for the `Value` trait.
pub struct _384; impl Value for _384 { const VALUE: u32 = 384; }
/// Type representing the value 512 for the `Value` trait.
pub struct _512; impl Value for _512 { const VALUE: u32 = 512; }
+99
View File
@@ -0,0 +1,99 @@
// 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/>.
//! An unsigned fixed-size integer.
#[cfg(feature = "std")]
use serde::{Serialize, Serializer, Deserialize, Deserializer};
#[cfg(feature = "std")]
use bytes;
macro_rules! impl_serde {
($name: ident, $len: expr) => {
#[cfg(feature = "std")]
impl Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
let mut bytes = [0u8; $len * 8];
self.to_big_endian(&mut bytes);
bytes::serialize_uint(&bytes, serializer)
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Between(0, $len * 8))
.map(|x| (&*x).into())
}
}
}
}
construct_uint!(U256, 4);
impl_serde!(U256, 4);
#[cfg(test)]
mod tests {
use super::*;
use substrate_serializer as ser;
macro_rules! test {
($name: ident, $test_name: ident) => {
#[test]
fn $test_name() {
let tests = vec![
($name::from(0), "0x0"),
($name::from(1), "0x1"),
($name::from(2), "0x2"),
($name::from(10), "0xa"),
($name::from(15), "0xf"),
($name::from(15), "0xf"),
($name::from(16), "0x10"),
($name::from(1_000), "0x3e8"),
($name::from(100_000), "0x186a0"),
($name::from(u64::max_value()), "0xffffffffffffffff"),
($name::from(u64::max_value()) + $name::from(1), "0x10000000000000000"),
];
for (number, expected) in tests {
assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number));
assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap());
}
// Invalid examples
assert!(ser::from_str::<$name>("\"0x\"").unwrap_err().is_data());
assert!(ser::from_str::<$name>("\"0xg\"").unwrap_err().is_data());
assert!(ser::from_str::<$name>("\"\"").unwrap_err().is_data());
assert!(ser::from_str::<$name>("\"10\"").unwrap_err().is_data());
assert!(ser::from_str::<$name>("\"0\"").unwrap_err().is_data());
}
}
}
test!(U256, test_u256);
#[test]
fn test_large_values() {
assert_eq!(
ser::to_string_pretty(&!U256::zero()),
"\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\""
);
assert!(
ser::from_str::<U256>("\"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"").unwrap_err().is_data()
);
}
}