Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
+69 -54
View File
@@ -17,13 +17,16 @@
//! Substrate changes trie configuration.
#[cfg(any(feature = "std", test))]
use serde::{Serialize, Deserialize};
use codec::{Encode, Decode};
use codec::{Decode, Encode};
use num_traits::Zero;
#[cfg(any(feature = "std", test))]
use serde::{Deserialize, Serialize};
/// Substrate changes trie configuration.
#[cfg_attr(any(feature = "std", test), derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf))]
#[cfg_attr(
any(feature = "std", test),
derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf)
)]
#[derive(Debug, Clone, PartialEq, Eq, Default, Encode, Decode)]
pub struct ChangesTrieConfiguration {
/// Interval (in blocks) at which level1-digests are created. Digests are not
@@ -62,32 +65,31 @@ impl ChangesTrieConfiguration {
}
/// Do we need to build digest at given block?
pub fn is_digest_build_required_at_block<Number>(
&self,
zero: Number,
block: Number,
) -> bool
where
Number: From<u32> + PartialEq +
::sp_std::ops::Rem<Output=Number> + ::sp_std::ops::Sub<Output=Number> +
::sp_std::cmp::PartialOrd + Zero,
pub fn is_digest_build_required_at_block<Number>(&self, zero: Number, block: Number) -> bool
where
Number: From<u32>
+ PartialEq
+ ::sp_std::ops::Rem<Output = Number>
+ ::sp_std::ops::Sub<Output = Number>
+ ::sp_std::cmp::PartialOrd
+ Zero,
{
block > zero
&& self.is_digest_build_enabled()
&& ((block - zero) % self.digest_interval.into()).is_zero()
block > zero &&
self.is_digest_build_enabled() &&
((block - zero) % self.digest_interval.into()).is_zero()
}
/// Returns max digest interval. One if digests are not created at all.
pub fn max_digest_interval(&self) -> u32 {
if !self.is_digest_build_enabled() {
return 1;
return 1
}
// we'll get >1 loop iteration only when bad configuration parameters are selected
let mut current_level = self.digest_levels;
loop {
if let Some(max_digest_interval) = self.digest_interval.checked_pow(current_level) {
return max_digest_interval;
return max_digest_interval
}
current_level -= 1;
@@ -97,25 +99,28 @@ impl ChangesTrieConfiguration {
/// Returns max level digest block number that has been created at block <= passed block number.
///
/// Returns None if digests are not created at all.
pub fn prev_max_level_digest_block<Number>(
&self,
zero: Number,
block: Number,
) -> Option<Number>
where
Number: Clone + From<u32> + PartialOrd + PartialEq +
::sp_std::ops::Add<Output=Number> + ::sp_std::ops::Sub<Output=Number> +
::sp_std::ops::Div<Output=Number> + ::sp_std::ops::Mul<Output=Number> + Zero,
pub fn prev_max_level_digest_block<Number>(&self, zero: Number, block: Number) -> Option<Number>
where
Number: Clone
+ From<u32>
+ PartialOrd
+ PartialEq
+ ::sp_std::ops::Add<Output = Number>
+ ::sp_std::ops::Sub<Output = Number>
+ ::sp_std::ops::Div<Output = Number>
+ ::sp_std::ops::Mul<Output = Number>
+ Zero,
{
if block <= zero {
return None;
return None
}
let (next_begin, next_end) = self.next_max_level_digest_range(zero.clone(), block.clone())?;
let (next_begin, next_end) =
self.next_max_level_digest_range(zero.clone(), block.clone())?;
// if 'next' digest includes our block, then it is a also a previous digest
if next_end == block {
return Some(block);
return Some(block)
}
// if previous digest ends at zero block, then there are no previous digest
@@ -136,13 +141,18 @@ impl ChangesTrieConfiguration {
zero: Number,
mut block: Number,
) -> Option<(Number, Number)>
where
Number: Clone + From<u32> + PartialOrd + PartialEq +
::sp_std::ops::Add<Output=Number> + ::sp_std::ops::Sub<Output=Number> +
::sp_std::ops::Div<Output=Number> + ::sp_std::ops::Mul<Output=Number>,
where
Number: Clone
+ From<u32>
+ PartialOrd
+ PartialEq
+ ::sp_std::ops::Add<Output = Number>
+ ::sp_std::ops::Sub<Output = Number>
+ ::sp_std::ops::Div<Output = Number>
+ ::sp_std::ops::Mul<Output = Number>,
{
if !self.is_digest_build_enabled() {
return None;
return None
}
if block <= zero {
@@ -152,7 +162,7 @@ impl ChangesTrieConfiguration {
let max_digest_interval: Number = self.max_digest_interval().into();
let max_digests_since_zero = (block.clone() - zero.clone()) / max_digest_interval.clone();
if max_digests_since_zero == 0.into() {
return Some((zero.clone() + 1.into(), zero + max_digest_interval));
return Some((zero.clone() + 1.into(), zero + max_digest_interval))
}
let last_max_digest_block = zero + max_digests_since_zero * max_digest_interval.clone();
Some(if block == last_max_digest_block {
@@ -169,14 +179,22 @@ impl ChangesTrieConfiguration {
/// digest interval (in blocks)
/// step between blocks we're interested in when digest is built
/// )
pub fn digest_level_at_block<Number>(&self, zero: Number, block: Number) -> Option<(u32, u32, u32)>
where
Number: Clone + From<u32> + PartialEq +
::sp_std::ops::Rem<Output=Number> + ::sp_std::ops::Sub<Output=Number> +
::sp_std::cmp::PartialOrd + Zero,
pub fn digest_level_at_block<Number>(
&self,
zero: Number,
block: Number,
) -> Option<(u32, u32, u32)>
where
Number: Clone
+ From<u32>
+ PartialEq
+ ::sp_std::ops::Rem<Output = Number>
+ ::sp_std::ops::Sub<Output = Number>
+ ::sp_std::cmp::PartialOrd
+ Zero,
{
if !self.is_digest_build_required_at_block(zero.clone(), block.clone()) {
return None;
return None
}
let relative_block = block - zero;
@@ -185,8 +203,9 @@ impl ChangesTrieConfiguration {
let mut digest_step = 1u32;
while current_level < self.digest_levels {
let new_digest_interval = match digest_interval.checked_mul(self.digest_interval) {
Some(new_digest_interval) if (relative_block.clone() % new_digest_interval.into()).is_zero()
=> new_digest_interval,
Some(new_digest_interval)
if (relative_block.clone() % new_digest_interval.into()).is_zero() =>
new_digest_interval,
_ => break,
};
@@ -195,11 +214,7 @@ impl ChangesTrieConfiguration {
current_level += 1;
}
Some((
current_level,
digest_interval,
digest_step,
))
Some((current_level, digest_interval, digest_step))
}
}
@@ -208,10 +223,7 @@ mod tests {
use super::ChangesTrieConfiguration;
fn config(interval: u32, levels: u32) -> ChangesTrieConfiguration {
ChangesTrieConfiguration {
digest_interval: interval,
digest_levels: levels,
}
ChangesTrieConfiguration { digest_interval: interval, digest_levels: levels }
}
#[test]
@@ -255,7 +267,10 @@ mod tests {
assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 8u64), Some((1, 8, 1)));
assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 64u64), Some((2, 64, 8)));
assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 512u64), Some((3, 512, 64)));
assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4096u64), Some((4, 4096, 512)));
assert_eq!(
config(8, 4).digest_level_at_block(zero, zero + 4096u64),
Some((4, 4096, 512))
);
assert_eq!(config(8, 4).digest_level_at_block(zero, zero + 4112u64), Some((1, 8, 1)));
}
+293 -159
View File
@@ -19,37 +19,35 @@
//! Cryptographic utilities.
// end::description[]
use crate::{sr25519, ed25519};
use sp_std::hash::Hash;
use sp_std::vec::Vec;
use sp_std::str;
#[cfg(feature = "std")]
use sp_std::convert::TryInto;
use sp_std::convert::TryFrom;
use crate::hexdisplay::HexDisplay;
use crate::{ed25519, sr25519};
#[cfg(feature = "std")]
use base58::{FromBase58, ToBase58};
use codec::{Decode, Encode, MaxEncodedLen};
#[cfg(feature = "std")]
use parking_lot::Mutex;
#[cfg(feature = "std")]
use rand::{RngCore, rngs::OsRng};
use codec::{Encode, Decode, MaxEncodedLen};
use rand::{rngs::OsRng, RngCore};
#[cfg(feature = "std")]
use regex::Regex;
#[cfg(feature = "std")]
use base58::{FromBase58, ToBase58};
#[cfg(feature = "std")]
use crate::hexdisplay::HexDisplay;
#[doc(hidden)]
pub use sp_std::ops::Deref;
use sp_runtime_interface::pass_by::PassByInner;
/// Trait to zeroize a memory buffer.
pub use zeroize::Zeroize;
/// Trait for accessing reference to `SecretString`.
pub use secrecy::ExposeSecret;
/// A store for sensitive data.
#[cfg(feature = "std")]
pub use secrecy::SecretString;
use sp_runtime_interface::pass_by::PassByInner;
#[cfg(feature = "std")]
use sp_std::convert::TryInto;
#[doc(hidden)]
pub use sp_std::ops::Deref;
use sp_std::{convert::TryFrom, hash::Hash, str, vec::Vec};
/// Trait to zeroize a memory buffer.
pub use zeroize::Zeroize;
/// The root phrase for our publicly known keys.
pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold race lonely fit walk";
pub const DEV_PHRASE: &str =
"bottom drive obey lake curtain smoke basket hold race lonely fit walk";
/// The address of the associated root phrase for our publicly known keys.
pub const DEV_ADDRESS: &str = "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV";
@@ -118,22 +116,28 @@ pub enum DeriveJunction {
#[cfg(feature = "full_crypto")]
impl DeriveJunction {
/// Consume self to return a soft derive junction with the same chain code.
pub fn soften(self) -> Self { DeriveJunction::Soft(self.unwrap_inner()) }
pub fn soften(self) -> Self {
DeriveJunction::Soft(self.unwrap_inner())
}
/// Consume self to return a hard derive junction with the same chain code.
pub fn harden(self) -> Self { DeriveJunction::Hard(self.unwrap_inner()) }
pub fn harden(self) -> Self {
DeriveJunction::Hard(self.unwrap_inner())
}
/// Create a new soft (vanilla) DeriveJunction from a given, encodable, value.
///
/// If you need a hard junction, use `hard()`.
pub fn soft<T: Encode>(index: T) -> Self {
let mut cc: [u8; JUNCTION_ID_LEN] = Default::default();
index.using_encoded(|data| if data.len() > JUNCTION_ID_LEN {
let hash_result = blake2_rfc::blake2b::blake2b(JUNCTION_ID_LEN, &[], data);
let hash = hash_result.as_bytes();
cc.copy_from_slice(hash);
} else {
cc[0..data.len()].copy_from_slice(data);
index.using_encoded(|data| {
if data.len() > JUNCTION_ID_LEN {
let hash_result = blake2_rfc::blake2b::blake2b(JUNCTION_ID_LEN, &[], data);
let hash = hash_result.as_bytes();
cc.copy_from_slice(hash);
} else {
cc[0..data.len()].copy_from_slice(data);
}
});
DeriveJunction::Soft(cc)
}
@@ -174,11 +178,8 @@ impl DeriveJunction {
impl<T: AsRef<str>> From<T> for DeriveJunction {
fn from(j: T) -> DeriveJunction {
let j = j.as_ref();
let (code, hard) = if let Some(stripped) = j.strip_prefix('/') {
(stripped, true)
} else {
(j, false)
};
let (code, hard) =
if let Some(stripped) = j.strip_prefix('/') { (stripped, true) } else { (j, false) };
let res = if let Ok(n) = str::parse::<u64>(code) {
// number
@@ -231,12 +232,11 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
/// Some if the string is a properly encoded SS58Check address.
#[cfg(feature = "std")]
fn from_ss58check(s: &str) -> Result<Self, PublicError> {
Self::from_ss58check_with_version(s)
.and_then(|(r, v)| match v {
v if !v.is_custom() => Ok(r),
v if v == *DEFAULT_VERSION.lock() => Ok(r),
_ => Err(PublicError::UnknownVersion),
})
Self::from_ss58check_with_version(s).and_then(|(r, v)| match v {
v if !v.is_custom() => Ok(r),
v if v == *DEFAULT_VERSION.lock() => Ok(r),
_ => Err(PublicError::UnknownVersion),
})
}
/// Some if the string is a properly encoded SS58Check address.
@@ -249,7 +249,9 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
let body_len = res.as_mut().len();
let data = s.from_base58().map_err(|_| PublicError::BadBase58)?;
if data.len() < 2 { return Err(PublicError::BadLength); }
if data.len() < 2 {
return Err(PublicError::BadLength)
}
let (prefix_len, ident) = match data[0] {
0..=63 => (1, data[0] as u16),
64..=127 => {
@@ -261,18 +263,22 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
let lower = (data[0] << 2) | (data[1] >> 6);
let upper = data[1] & 0b00111111;
(2, (lower as u16) | ((upper as u16) << 8))
}
},
_ => return Err(PublicError::UnknownVersion),
};
if data.len() != prefix_len + body_len + CHECKSUM_LEN { return Err(PublicError::BadLength) }
if data.len() != prefix_len + body_len + CHECKSUM_LEN {
return Err(PublicError::BadLength)
}
let format = ident.try_into().map_err(|_: ()| PublicError::UnknownVersion)?;
if !Self::format_is_allowed(format) { return Err(PublicError::FormatNotAllowed) }
if !Self::format_is_allowed(format) {
return Err(PublicError::FormatNotAllowed)
}
let hash = ss58hash(&data[0..body_len + prefix_len]);
let checksum = &hash.as_bytes()[0..CHECKSUM_LEN];
if data[body_len + prefix_len..body_len + prefix_len + CHECKSUM_LEN] != *checksum {
// Invalid checksum.
return Err(PublicError::InvalidChecksum);
return Err(PublicError::InvalidChecksum)
}
res.as_mut().copy_from_slice(&data[prefix_len..body_len + prefix_len]);
Ok((res, format))
@@ -282,12 +288,11 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
/// a derivation path following.
#[cfg(feature = "std")]
fn from_string(s: &str) -> Result<Self, PublicError> {
Self::from_string_with_version(s)
.and_then(|(r, v)| match v {
v if !v.is_custom() => Ok(r),
v if v == *DEFAULT_VERSION.lock() => Ok(r),
_ => Err(PublicError::UnknownVersion),
})
Self::from_string_with_version(s).and_then(|(r, v)| match v {
v if !v.is_custom() => Ok(r),
v if v == *DEFAULT_VERSION.lock() => Ok(r),
_ => Err(PublicError::UnknownVersion),
})
}
/// Return the ss58-check string for this key.
@@ -304,7 +309,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
// lower bits of the upper byte in the low pos
let second = ((ident >> 8) as u8) | ((ident & 0b0000_0000_0000_0011) as u8) << 6;
vec![first | 0b01000000, second]
}
},
_ => unreachable!("masked out the upper two bits; qed"),
};
v.extend(self.as_ref());
@@ -315,7 +320,9 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
/// Return the ss58-check string for this key.
#[cfg(feature = "std")]
fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) }
fn to_ss58check(&self) -> String {
self.to_ss58check_with_version(*DEFAULT_VERSION.lock())
}
/// Some if the string is a properly encoded SS58Check address, optionally with
/// a derivation path following.
@@ -331,7 +338,7 @@ pub trait Derive: Sized {
///
/// Will be `None` for public keys if there are any hard junctions in there.
#[cfg(feature = "std")]
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self, _path: Iter) -> Option<Self> {
fn derive<Iter: Iterator<Item = DeriveJunction>>(&self, _path: Iter) -> Option<Self> {
None
}
}
@@ -629,9 +636,7 @@ lazy_static::lazy_static! {
impl<T: Sized + AsMut<[u8]> + AsRef<[u8]> + Default + Derive> Ss58Codec for T {
fn from_string(s: &str) -> Result<Self, PublicError> {
let cap = SS58_REGEX.captures(s).ok_or(PublicError::InvalidFormat)?;
let s = cap.name("ss58")
.map(|r| r.as_str())
.unwrap_or(DEV_ADDRESS);
let s = cap.name("ss58").map(|r| r.as_str()).unwrap_or(DEV_ADDRESS);
let addr = if let Some(stripped) = s.strip_prefix("0x") {
let d = hex::decode(stripped).map_err(|_| PublicError::InvalidFormat)?;
let mut r = Self::default();
@@ -647,28 +652,23 @@ impl<T: Sized + AsMut<[u8]> + AsRef<[u8]> + Default + Derive> Ss58Codec for T {
if cap["path"].is_empty() {
Ok(addr)
} else {
let path = JUNCTION_REGEX.captures_iter(&cap["path"])
.map(|f| DeriveJunction::from(&f[1]));
addr.derive(path)
.ok_or(PublicError::InvalidPath)
let path =
JUNCTION_REGEX.captures_iter(&cap["path"]).map(|f| DeriveJunction::from(&f[1]));
addr.derive(path).ok_or(PublicError::InvalidPath)
}
}
fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
let cap = SS58_REGEX.captures(s).ok_or(PublicError::InvalidFormat)?;
let (addr, v) = Self::from_ss58check_with_version(
cap.name("ss58")
.map(|r| r.as_str())
.unwrap_or(DEV_ADDRESS)
cap.name("ss58").map(|r| r.as_str()).unwrap_or(DEV_ADDRESS),
)?;
if cap["path"].is_empty() {
Ok((addr, v))
} else {
let path = JUNCTION_REGEX.captures_iter(&cap["path"])
.map(|f| DeriveJunction::from(&f[1]));
addr.derive(path)
.ok_or(PublicError::InvalidPath)
.map(|a| (a, v))
let path =
JUNCTION_REGEX.captures_iter(&cap["path"]).map(|f| DeriveJunction::from(&f[1]));
addr.derive(path).ok_or(PublicError::InvalidPath).map(|a| (a, v))
}
}
}
@@ -694,10 +694,14 @@ pub trait Public:
fn from_slice(data: &[u8]) -> Self;
/// Return a `Vec<u8>` filled with raw data.
fn to_raw_vec(&self) -> Vec<u8> { self.as_slice().to_vec() }
fn to_raw_vec(&self) -> Vec<u8> {
self.as_slice().to_vec()
}
/// Return a slice filled with raw data.
fn as_slice(&self) -> &[u8] { self.as_ref() }
fn as_slice(&self) -> &[u8] {
self.as_ref()
}
/// Return `CryptoTypePublicPair` from public key.
fn to_public_crypto_pair(&self) -> CryptoTypePublicPair;
}
@@ -809,14 +813,20 @@ impl sp_std::fmt::Debug for AccountId32 {
#[cfg(feature = "std")]
impl serde::Serialize for AccountId32 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_ss58check())
}
}
#[cfg(feature = "std")]
impl<'de> serde::Deserialize<'de> for AccountId32 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ss58Codec::from_ss58check(&String::deserialize(deserializer)?)
.map_err(|e| serde::de::Error::custom(format!("{:?}", e)))
}
@@ -851,11 +861,13 @@ mod dummy {
pub struct Dummy;
impl AsRef<[u8]> for Dummy {
fn as_ref(&self) -> &[u8] { &b""[..] }
fn as_ref(&self) -> &[u8] {
&b""[..]
}
}
impl AsMut<[u8]> for Dummy {
fn as_mut(&mut self) -> &mut[u8] {
fn as_mut(&mut self) -> &mut [u8] {
unsafe {
#[allow(mutable_transmutes)]
sp_std::mem::transmute::<_, &'static mut [u8]>(&b""[..])
@@ -878,14 +890,18 @@ mod dummy {
impl Derive for Dummy {}
impl Public for Dummy {
fn from_slice(_: &[u8]) -> Self { Self }
fn from_slice(_: &[u8]) -> Self {
Self
}
#[cfg(feature = "std")]
fn to_raw_vec(&self) -> Vec<u8> { vec![] }
fn as_slice(&self) -> &[u8] { b"" }
fn to_raw_vec(&self) -> Vec<u8> {
vec![]
}
fn as_slice(&self) -> &[u8] {
b""
}
fn to_public_crypto_pair(&self) -> CryptoTypePublicPair {
CryptoTypePublicPair(
CryptoTypeId(*b"dumm"), Public::to_raw_vec(self)
)
CryptoTypePublicPair(CryptoTypeId(*b"dumm"), Public::to_raw_vec(self))
}
}
@@ -895,23 +911,41 @@ mod dummy {
type Signature = Dummy;
type DeriveError = ();
#[cfg(feature = "std")]
fn generate_with_phrase(_: Option<&str>) -> (Self, String, Self::Seed) { Default::default() }
fn generate_with_phrase(_: Option<&str>) -> (Self, String, Self::Seed) {
Default::default()
}
#[cfg(feature = "std")]
fn from_phrase(_: &str, _: Option<&str>)
-> Result<(Self, Self::Seed), SecretStringError>
{
fn from_phrase(_: &str, _: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError> {
Ok(Default::default())
}
fn derive<
Iter: Iterator<Item=DeriveJunction>,
>(&self, _: Iter, _: Option<Dummy>) -> Result<(Self, Option<Dummy>), Self::DeriveError> { Ok((Self, None)) }
fn from_seed(_: &Self::Seed) -> Self { Self }
fn from_seed_slice(_: &[u8]) -> Result<Self, SecretStringError> { Ok(Self) }
fn sign(&self, _: &[u8]) -> Self::Signature { Self }
fn verify<M: AsRef<[u8]>>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true }
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(_: &[u8], _: M, _: P) -> bool { true }
fn public(&self) -> Self::Public { Self }
fn to_raw_vec(&self) -> Vec<u8> { vec![] }
fn derive<Iter: Iterator<Item = DeriveJunction>>(
&self,
_: Iter,
_: Option<Dummy>,
) -> Result<(Self, Option<Dummy>), Self::DeriveError> {
Ok((Self, None))
}
fn from_seed(_: &Self::Seed) -> Self {
Self
}
fn from_seed_slice(_: &[u8]) -> Result<Self, SecretStringError> {
Ok(Self)
}
fn sign(&self, _: &[u8]) -> Self::Signature {
Self
}
fn verify<M: AsRef<[u8]>>(_: &Self::Signature, _: M, _: &Self::Public) -> bool {
true
}
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(_: &[u8], _: M, _: P) -> bool {
true
}
fn public(&self) -> Self::Public {
Self
}
fn to_raw_vec(&self) -> Vec<u8> {
vec![]
}
}
}
@@ -956,10 +990,14 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
/// Returns the KeyPair from the English BIP39 seed `phrase`, or `None` if it's invalid.
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>;
fn from_phrase(
phrase: &str,
password: Option<&str>,
) -> Result<(Self, Self::Seed), SecretStringError>;
/// Derive a child key from a series of given junctions.
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self,
fn derive<Iter: Iterator<Item = DeriveJunction>>(
&self,
path: Iter,
seed: Option<Self::Seed>,
) -> Result<(Self, Option<Self::Seed>), Self::DeriveError>;
@@ -1018,19 +1056,20 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
///
/// `None` is returned if no matches are found.
#[cfg(feature = "std")]
fn from_string_with_seed(s: &str, password_override: Option<&str>)
-> Result<(Self, Option<Self::Seed>), SecretStringError>
{
fn from_string_with_seed(
s: &str,
password_override: Option<&str>,
) -> Result<(Self, Option<Self::Seed>), SecretStringError> {
let cap = SECRET_PHRASE_REGEX.captures(s).ok_or(SecretStringError::InvalidFormat)?;
let path = JUNCTION_REGEX.captures_iter(&cap["path"])
.map(|f| DeriveJunction::from(&f[1]));
let path = JUNCTION_REGEX.captures_iter(&cap["path"]).map(|f| DeriveJunction::from(&f[1]));
let phrase = cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE);
let password = password_override.or_else(|| cap.name("password").map(|m| m.as_str()));
let (root, seed) = if let Some(stripped) = phrase.strip_prefix("0x") {
hex::decode(stripped).ok()
hex::decode(stripped)
.ok()
.and_then(|seed_vec| {
let mut seed = Self::Seed::default();
if seed.as_ref().len() == seed_vec.len() {
@@ -1042,8 +1081,7 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
})
.ok_or(SecretStringError::InvalidSeed)?
} else {
Self::from_phrase(phrase, password)
.map_err(|_| SecretStringError::InvalidPhrase)?
Self::from_phrase(phrase, password).map_err(|_| SecretStringError::InvalidPhrase)?
};
root.derive(path, Some(seed)).map_err(|_| SecretStringError::InvalidPath)
}
@@ -1074,19 +1112,25 @@ pub trait Wraps: Sized {
type Inner: IsWrappedBy<Self>;
}
impl<T, Outer> IsWrappedBy<Outer> for T where
impl<T, Outer> IsWrappedBy<Outer> for T
where
Outer: AsRef<Self> + AsMut<Self> + From<Self>,
T: From<Outer>,
{
/// Get a reference to the inner from the outer.
fn from_ref(outer: &Outer) -> &Self { outer.as_ref() }
fn from_ref(outer: &Outer) -> &Self {
outer.as_ref()
}
/// Get a mutable reference to the inner from the outer.
fn from_mut(outer: &mut Outer) -> &mut Self { outer.as_mut() }
fn from_mut(outer: &mut Outer) -> &mut Self {
outer.as_mut()
}
}
impl<Inner, Outer, T> UncheckedFrom<T> for Outer where
Outer: Wraps<Inner=Inner>,
impl<Inner, Outer, T> UncheckedFrom<T> for Outer
where
Outer: Wraps<Inner = Inner>,
Inner: IsWrappedBy<Outer> + UncheckedFrom<T>,
{
fn unchecked_from(t: T) -> Self {
@@ -1110,8 +1154,18 @@ pub trait CryptoType {
/// Values whose first character is `_` are reserved for private use and won't conflict with any
/// public modules.
#[derive(
Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode, PassByInner,
crate::RuntimeDebug
Copy,
Clone,
Default,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Encode,
Decode,
PassByInner,
crate::RuntimeDebug,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct KeyTypeId(pub [u8; 4]);
@@ -1134,7 +1188,7 @@ impl<'a> TryFrom<&'a str> for KeyTypeId {
fn try_from(x: &'a str) -> Result<Self, ()> {
let b = x.as_bytes();
if b.len() != 4 {
return Err(());
return Err(())
}
let mut res = KeyTypeId::default();
res.0.copy_from_slice(&b[0..4]);
@@ -1159,7 +1213,7 @@ impl sp_std::fmt::Display for CryptoTypePublicPair {
Ok(id) => id.to_string(),
Err(_) => {
format!("{:#?}", self.0)
}
},
};
write!(f, "{}-{}", id, HexDisplay::from(&self.1))
}
@@ -1195,16 +1249,16 @@ pub mod key_types {
#[cfg(test)]
mod tests {
use super::*;
use crate::DeriveJunction;
use hex_literal::hex;
use super::*;
#[derive(Clone, Eq, PartialEq, Debug)]
enum TestPair {
Generated,
GeneratedWithPhrase,
GeneratedFromPhrase{phrase: String, password: Option<String>},
Standard{phrase: String, password: Option<String>, path: Vec<DeriveJunction>},
GeneratedFromPhrase { phrase: String, password: Option<String> },
Standard { phrase: String, password: Option<String>, path: Vec<DeriveJunction> },
Seed(Vec<u8>),
}
impl Default for TestPair {
@@ -1250,9 +1304,7 @@ mod tests {
vec![]
}
fn to_public_crypto_pair(&self) -> CryptoTypePublicPair {
CryptoTypePublicPair(
CryptoTypeId(*b"dumm"), self.to_raw_vec(),
)
CryptoTypePublicPair(CryptoTypeId(*b"dumm"), self.to_raw_vec())
}
}
impl Pair for TestPair {
@@ -1261,41 +1313,68 @@ mod tests {
type Signature = [u8; 0];
type DeriveError = ();
fn generate() -> (Self, <Self as Pair>::Seed) { (TestPair::Generated, [0u8; 8]) }
fn generate() -> (Self, <Self as Pair>::Seed) {
(TestPair::Generated, [0u8; 8])
}
fn generate_with_phrase(_password: Option<&str>) -> (Self, String, <Self as Pair>::Seed) {
(TestPair::GeneratedWithPhrase, "".into(), [0u8; 8])
}
fn from_phrase(phrase: &str, password: Option<&str>)
-> Result<(Self, <Self as Pair>::Seed), SecretStringError>
{
Ok((TestPair::GeneratedFromPhrase {
phrase: phrase.to_owned(),
password: password.map(Into::into)
}, [0u8; 8]))
fn from_phrase(
phrase: &str,
password: Option<&str>,
) -> Result<(Self, <Self as Pair>::Seed), SecretStringError> {
Ok((
TestPair::GeneratedFromPhrase {
phrase: phrase.to_owned(),
password: password.map(Into::into),
},
[0u8; 8],
))
}
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self, path_iter: Iter, _: Option<[u8; 8]>)
-> Result<(Self, Option<[u8; 8]>), Self::DeriveError>
{
Ok((match self.clone() {
TestPair::Standard {phrase, password, path} =>
TestPair::Standard { phrase, password, path: path.into_iter().chain(path_iter).collect() },
TestPair::GeneratedFromPhrase {phrase, password} =>
TestPair::Standard { phrase, password, path: path_iter.collect() },
x => if path_iter.count() == 0 { x } else { return Err(()) },
}, None))
fn derive<Iter: Iterator<Item = DeriveJunction>>(
&self,
path_iter: Iter,
_: Option<[u8; 8]>,
) -> Result<(Self, Option<[u8; 8]>), Self::DeriveError> {
Ok((
match self.clone() {
TestPair::Standard { phrase, password, path } => TestPair::Standard {
phrase,
password,
path: path.into_iter().chain(path_iter).collect(),
},
TestPair::GeneratedFromPhrase { phrase, password } =>
TestPair::Standard { phrase, password, path: path_iter.collect() },
x =>
if path_iter.count() == 0 {
x
} else {
return Err(())
},
},
None,
))
}
fn from_seed(_seed: &<TestPair as Pair>::Seed) -> Self {
TestPair::Seed(_seed.as_ref().to_owned())
}
fn sign(&self, _message: &[u8]) -> Self::Signature {
[]
}
fn verify<M: AsRef<[u8]>>(_: &Self::Signature, _: M, _: &Self::Public) -> bool {
true
}
fn from_seed(_seed: &<TestPair as Pair>::Seed) -> Self { TestPair::Seed(_seed.as_ref().to_owned()) }
fn sign(&self, _message: &[u8]) -> Self::Signature { [] }
fn verify<M: AsRef<[u8]>>(_: &Self::Signature, _: M, _: &Self::Public) -> bool { true }
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(
_sig: &[u8],
_message: M,
_pubkey: P
) -> bool { true }
fn public(&self) -> Self::Public { TestPublic }
fn from_seed_slice(seed: &[u8])
-> Result<Self, SecretStringError>
{
_pubkey: P,
) -> bool {
true
}
fn public(&self) -> Self::Public {
TestPublic
}
fn from_seed_slice(seed: &[u8]) -> Result<Self, SecretStringError> {
Ok(TestPair::Seed(seed.to_owned()))
}
fn to_raw_vec(&self) -> Vec<u8> {
@@ -1327,43 +1406,83 @@ mod tests {
fn interpret_std_secret_string_should_work() {
assert_eq!(
TestPair::from_string("hello world", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: None,
path: vec![]
})
);
assert_eq!(
TestPair::from_string("hello world/1", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::soft(1)]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: None,
path: vec![DeriveJunction::soft(1)]
})
);
assert_eq!(
TestPair::from_string("hello world/DOT", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::soft("DOT")]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: None,
path: vec![DeriveJunction::soft("DOT")]
})
);
assert_eq!(
TestPair::from_string("hello world//1", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard(1)]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: None,
path: vec![DeriveJunction::hard(1)]
})
);
assert_eq!(
TestPair::from_string("hello world//DOT", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard("DOT")]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: None,
path: vec![DeriveJunction::hard("DOT")]
})
);
assert_eq!(
TestPair::from_string("hello world//1/DOT", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: None,
path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]
})
);
assert_eq!(
TestPair::from_string("hello world//DOT/1", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: None, path: vec![DeriveJunction::hard("DOT"), DeriveJunction::soft(1)]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: None,
path: vec![DeriveJunction::hard("DOT"), DeriveJunction::soft(1)]
})
);
assert_eq!(
TestPair::from_string("hello world///password", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: Some("password".to_owned()),
path: vec![]
})
);
assert_eq!(
TestPair::from_string("hello world//1/DOT///password", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: Some("password".to_owned()),
path: vec![DeriveJunction::hard(1), DeriveJunction::soft("DOT")]
})
);
assert_eq!(
TestPair::from_string("hello world/1//DOT///password", None),
Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![DeriveJunction::soft(1), DeriveJunction::hard("DOT")]})
Ok(TestPair::Standard {
phrase: "hello world".to_owned(),
password: Some("password".to_owned()),
path: vec![DeriveJunction::soft(1), DeriveJunction::hard("DOT")]
})
);
}
@@ -1371,25 +1490,40 @@ mod tests {
fn accountid_32_from_str_works() {
use std::str::FromStr;
assert!(AccountId32::from_str("5G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").is_ok());
assert!(AccountId32::from_str("5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok());
assert!(AccountId32::from_str("0x5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok());
assert!(AccountId32::from_str(
"5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d"
)
.is_ok());
assert!(AccountId32::from_str(
"0x5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d"
)
.is_ok());
assert_eq!(
AccountId32::from_str("99G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").unwrap_err(),
"invalid ss58 address.",
);
assert_eq!(
AccountId32::from_str("gc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(),
AccountId32::from_str(
"gc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d"
)
.unwrap_err(),
"invalid hex address.",
);
assert_eq!(
AccountId32::from_str("0xgc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(),
AccountId32::from_str(
"0xgc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d"
)
.unwrap_err(),
"invalid hex address.",
);
// valid hex but invalid length will be treated as ss58.
assert_eq!(
AccountId32::from_str("55c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(),
AccountId32::from_str(
"55c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d"
)
.unwrap_err(),
"invalid ss58 address.",
);
}
+92 -54
View File
@@ -22,25 +22,30 @@
#[cfg(feature = "full_crypto")]
use sp_std::vec::Vec;
use codec::{Decode, Encode, MaxEncodedLen};
use sp_std::cmp::Ordering;
use codec::{Encode, Decode, MaxEncodedLen};
#[cfg(feature = "full_crypto")]
use core::convert::{TryFrom, TryInto};
#[cfg(feature = "std")]
use substrate_bip39::seed_from_entropy;
#[cfg(feature = "std")]
use bip39::{Mnemonic, Language, MnemonicType};
#[cfg(feature = "full_crypto")]
use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}};
#[cfg(feature = "std")]
use crate::crypto::Ss58Codec;
use crate::crypto::{
CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, UncheckedFrom,
};
#[cfg(feature = "full_crypto")]
use crate::{
crypto::{DeriveJunction, Pair as TraitPair, SecretStringError},
hashing::blake2_256,
};
#[cfg(feature = "std")]
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId};
use sp_runtime_interface::pass_by::PassByInner;
use bip39::{Language, Mnemonic, MnemonicType};
#[cfg(feature = "full_crypto")]
use core::convert::{TryFrom, TryInto};
#[cfg(feature = "full_crypto")]
use secp256k1::{PublicKey, SecretKey};
#[cfg(feature = "std")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use sp_runtime_interface::pass_by::PassByInner;
#[cfg(feature = "std")]
use substrate_bip39::seed_from_entropy;
/// An identifier used to match public keys against ecdsa keys
pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ecds");
@@ -165,7 +170,6 @@ impl sp_std::convert::TryFrom<&[u8]> for Public {
if data.len() == 33 {
Ok(Self::from_slice(data))
} else {
Err(())
}
}
@@ -206,14 +210,20 @@ impl sp_std::fmt::Debug for Public {
#[cfg(feature = "std")]
impl Serialize for Public {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_ss58check())
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for Public {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Public::from_ss58check(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))
}
@@ -246,14 +256,20 @@ impl sp_std::convert::TryFrom<&[u8]> for Signature {
#[cfg(feature = "std")]
impl Serialize for Signature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&hex::encode(self))
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for Signature {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let signature_hex = hex::decode(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))?;
Signature::try_from(signature_hex.as_ref())
@@ -359,7 +375,7 @@ impl Signature {
#[cfg(feature = "full_crypto")]
pub fn recover_prehashed(&self, message: &[u8; 32]) -> Option<Public> {
let message = secp256k1::Message::parse(message);
let sig: (_, _) = self.try_into().ok()?;
secp256k1::recover(&message, &sig.0, &sig.1)
@@ -381,7 +397,9 @@ impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature {
#[cfg(feature = "full_crypto")]
impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) {
type Error = ();
fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> {
fn try_from(
x: &'a Signature,
) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> {
Ok((
secp256k1::Signature::parse_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"),
secp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?,
@@ -430,21 +448,22 @@ impl TraitPair for Pair {
let phrase = mnemonic.phrase();
let (pair, seed) = Self::from_phrase(phrase, password)
.expect("All phrases generated by Mnemonic are valid; qed");
(
pair,
phrase.to_owned(),
seed,
)
(pair, phrase.to_owned(), seed)
}
/// Generate key pair from given recovery phrase and password.
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
fn from_phrase(
phrase: &str,
password: Option<&str>,
) -> Result<(Pair, Seed), SecretStringError> {
let big_seed = seed_from_entropy(
Mnemonic::from_phrase(phrase, Language::English)
.map_err(|_| SecretStringError::InvalidPhrase)?.entropy(),
.map_err(|_| SecretStringError::InvalidPhrase)?
.entropy(),
password.unwrap_or(""),
).map_err(|_| SecretStringError::InvalidSeed)?;
)
.map_err(|_| SecretStringError::InvalidSeed)?;
let mut seed = Seed::default();
seed.copy_from_slice(&big_seed[0..32]);
Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed))
@@ -462,16 +481,17 @@ impl TraitPair for Pair {
///
/// You should never need to use this; generate(), generate_with_phrase
fn from_seed_slice(seed_slice: &[u8]) -> Result<Pair, SecretStringError> {
let secret = SecretKey::parse_slice(seed_slice)
.map_err(|_| SecretStringError::InvalidSeedLength)?;
let secret =
SecretKey::parse_slice(seed_slice).map_err(|_| SecretStringError::InvalidSeedLength)?;
let public = PublicKey::from_secret_key(&secret);
Ok(Pair{ public, secret })
Ok(Pair { public, secret })
}
/// Derive a child key from a series of given junctions.
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self,
fn derive<Iter: Iterator<Item = DeriveJunction>>(
&self,
path: Iter,
_seed: Option<Seed>
_seed: Option<Seed>,
) -> Result<(Pair, Option<Seed>), DeriveError> {
let mut acc = self.secret.serialize();
for j in path {
@@ -497,7 +517,10 @@ impl TraitPair for Pair {
/// Verify a signature on a message. Returns true if the signature is good.
fn verify<M: AsRef<[u8]>>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool {
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
let sig: (_, _) = match sig.try_into() { Ok(x) => x, _ => return false };
let sig: (_, _) = match sig.try_into() {
Ok(x) => x,
_ => return false,
};
match secp256k1::recover(&message, &sig.0, &sig.1) {
Ok(actual) => pubkey.0[..] == actual.serialize_compressed()[..],
_ => false,
@@ -510,9 +533,17 @@ impl TraitPair for Pair {
/// size. Use it only if you're coming from byte buffers and need the speed.
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool {
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
if sig.len() != 65 { return false }
let ri = match secp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false };
let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) { Ok(x) => x, _ => return false };
if sig.len() != 65 {
return false
}
let ri = match secp256k1::RecoveryId::parse(sig[64]) {
Ok(x) => x,
_ => return false,
};
let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) {
Ok(x) => x,
_ => return false,
};
match secp256k1::recover(&message, &sig, &ri) {
Ok(actual) => pubkey.as_ref() == &actual.serialize()[1..],
_ => false,
@@ -554,30 +585,30 @@ impl Pair {
/// and thus matches the given `public` key.
pub fn verify_prehashed(sig: &Signature, message: &[u8; 32], public: &Public) -> bool {
let message = secp256k1::Message::parse(message);
let sig: (_, _) = match sig.try_into() {
Ok(x) => x,
_ => return false,
};
match secp256k1::recover(&message, &sig.0, &sig.1) {
Ok(actual) => public.0[..] == actual.serialize_compressed()[..],
_ => false,
}
}
}
}
impl CryptoType for Public {
#[cfg(feature="full_crypto")]
#[cfg(feature = "full_crypto")]
type Pair = Pair;
}
impl CryptoType for Signature {
#[cfg(feature="full_crypto")]
#[cfg(feature = "full_crypto")]
type Pair = Pair;
}
#[cfg(feature="full_crypto")]
#[cfg(feature = "full_crypto")]
impl CryptoType for Pair {
type Pair = Pair;
}
@@ -585,16 +616,20 @@ impl CryptoType for Pair {
#[cfg(test)]
mod test {
use super::*;
use crate::{
crypto::{set_default_ss58_version, PublicError, DEV_PHRASE},
keccak_256,
};
use hex_literal::hex;
use crate::{crypto::{DEV_PHRASE, set_default_ss58_version}, keccak_256};
use serde_json;
use crate::crypto::PublicError;
#[test]
fn default_phrase_should_be_used() {
assert_eq!(
Pair::from_string("//Alice///password", None).unwrap().public(),
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(),
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password"))
.unwrap()
.public(),
);
}
@@ -613,9 +648,9 @@ mod test {
#[test]
fn test_vector_should_work() {
let pair = Pair::from_seed(
&hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60")
);
let pair = Pair::from_seed(&hex!(
"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"
));
let public = pair.public();
assert_eq!(
public,
@@ -634,8 +669,9 @@ mod test {
fn test_vector_by_string_should_work() {
let pair = Pair::from_string(
"0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
None
).unwrap();
None,
)
.unwrap();
let public = pair.public();
assert_eq!(
public,
@@ -803,7 +839,8 @@ mod test {
// `msg` shouldn't be mangled
let msg = [0u8; 32];
let sig1 = pair.sign_prehashed(&msg);
let sig2: Signature = secp256k1::sign(&secp256k1::Message::parse(&msg), &pair.secret).into();
let sig2: Signature =
secp256k1::sign(&secp256k1::Message::parse(&msg), &pair.secret).into();
assert_eq!(sig1, sig2);
@@ -815,15 +852,16 @@ mod test {
// using pre-hashed `msg` works
let msg = keccak_256(b"this should be hashed");
let sig1 = pair.sign_prehashed(&msg);
let sig2: Signature = secp256k1::sign(&secp256k1::Message::parse(&msg), &pair.secret).into();
let sig2: Signature =
secp256k1::sign(&secp256k1::Message::parse(&msg), &pair.secret).into();
assert_eq!(sig1, sig2);
assert_eq!(sig1, sig2);
}
#[test]
fn verify_prehashed_works() {
let (pair, _, _) = Pair::generate_with_phrase(Some("password"));
// `msg` and `sig` match
let msg = keccak_256(b"this should be hashed");
let sig = pair.sign_prehashed(&msg);
+72 -45
View File
@@ -22,26 +22,28 @@
#[cfg(feature = "full_crypto")]
use sp_std::vec::Vec;
use crate::{hash::H256, hash::H512};
use codec::{Encode, Decode, MaxEncodedLen};
use crate::hash::{H256, H512};
use codec::{Decode, Encode, MaxEncodedLen};
#[cfg(feature = "std")]
use crate::crypto::Ss58Codec;
use crate::crypto::{
CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, UncheckedFrom,
};
#[cfg(feature = "full_crypto")]
use crate::crypto::{DeriveJunction, Pair as TraitPair, SecretStringError};
#[cfg(feature = "std")]
use bip39::{Language, Mnemonic, MnemonicType};
#[cfg(feature = "full_crypto")]
use core::convert::TryFrom;
#[cfg(feature = "full_crypto")]
use ed25519_dalek::{Signer as _, Verifier as _};
#[cfg(feature = "std")]
use substrate_bip39::seed_from_entropy;
#[cfg(feature = "std")]
use bip39::{Mnemonic, Language, MnemonicType};
#[cfg(feature = "full_crypto")]
use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError};
#[cfg(feature = "std")]
use crate::crypto::Ss58Codec;
#[cfg(feature = "std")]
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use sp_runtime_interface::pass_by::PassByInner;
use sp_std::ops::Deref;
#[cfg(feature = "std")]
use substrate_bip39::seed_from_entropy;
/// An identifier used to match public keys against ed25519 keys
pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ed25");
@@ -55,8 +57,7 @@ type Seed = [u8; 32];
/// A public key.
#[cfg_attr(feature = "full_crypto", derive(Hash))]
#[derive(
PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner,
MaxEncodedLen,
PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner, MaxEncodedLen,
)]
pub struct Public(pub [u8; 32]);
@@ -70,7 +71,7 @@ impl Clone for Pair {
Pair(ed25519_dalek::Keypair {
public: self.0.public,
secret: ed25519_dalek::SecretKey::from_bytes(self.0.secret.as_bytes())
.expect("key is always the correct size; qed")
.expect("key is always the correct size; qed"),
})
}
}
@@ -177,14 +178,20 @@ impl sp_std::fmt::Debug for Public {
#[cfg(feature = "std")]
impl Serialize for Public {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_ss58check())
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for Public {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Public::from_ss58check(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))
}
@@ -210,14 +217,20 @@ impl sp_std::convert::TryFrom<&[u8]> for Signature {
#[cfg(feature = "std")]
impl Serialize for Signature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&hex::encode(self))
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for Signature {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let signature_hex = hex::decode(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))?;
Signature::try_from(signature_hex.as_ref())
@@ -438,21 +451,22 @@ impl TraitPair for Pair {
let phrase = mnemonic.phrase();
let (pair, seed) = Self::from_phrase(phrase, password)
.expect("All phrases generated by Mnemonic are valid; qed");
(
pair,
phrase.to_owned(),
seed,
)
(pair, phrase.to_owned(), seed)
}
/// Generate key pair from given recovery phrase and password.
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
fn from_phrase(
phrase: &str,
password: Option<&str>,
) -> Result<(Pair, Seed), SecretStringError> {
let big_seed = seed_from_entropy(
Mnemonic::from_phrase(phrase, Language::English)
.map_err(|_| SecretStringError::InvalidPhrase)?.entropy(),
.map_err(|_| SecretStringError::InvalidPhrase)?
.entropy(),
password.unwrap_or(""),
).map_err(|_| SecretStringError::InvalidSeed)?;
)
.map_err(|_| SecretStringError::InvalidSeed)?;
let mut seed = Seed::default();
seed.copy_from_slice(&big_seed[0..32]);
Self::from_seed_slice(&big_seed[0..32]).map(|x| (x, seed))
@@ -477,7 +491,8 @@ impl TraitPair for Pair {
}
/// Derive a child key from a series of given junctions.
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self,
fn derive<Iter: Iterator<Item = DeriveJunction>>(
&self,
path: Iter,
_seed: Option<Seed>,
) -> Result<(Pair, Option<Seed>), DeriveError> {
@@ -522,7 +537,7 @@ impl TraitPair for Pair {
let sig = match ed25519_dalek::Signature::try_from(sig) {
Ok(s) => s,
Err(_) => return false
Err(_) => return false,
};
public_key.verify(message.as_ref(), &sig).is_ok()
@@ -572,15 +587,17 @@ impl CryptoType for Pair {
#[cfg(test)]
mod test {
use super::*;
use hex_literal::hex;
use crate::crypto::DEV_PHRASE;
use hex_literal::hex;
use serde_json;
#[test]
fn default_phrase_should_be_used() {
assert_eq!(
Pair::from_string("//Alice///password", None).unwrap().public(),
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(),
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password"))
.unwrap()
.public(),
);
}
@@ -599,13 +616,16 @@ mod test {
#[test]
fn test_vector_should_work() {
let pair = Pair::from_seed(
&hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60")
);
let public = pair.public();
assert_eq!(public, Public::from_raw(
hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a")
let pair = Pair::from_seed(&hex!(
"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"
));
let public = pair.public();
assert_eq!(
public,
Public::from_raw(hex!(
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"
))
);
let message = b"";
let signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b");
let signature = Signature::from_raw(signature);
@@ -617,12 +637,16 @@ mod test {
fn test_vector_by_string_should_work() {
let pair = Pair::from_string(
"0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
None
).unwrap();
None,
)
.unwrap();
let public = pair.public();
assert_eq!(public, Public::from_raw(
hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a")
));
assert_eq!(
public,
Public::from_raw(hex!(
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"
))
);
let message = b"";
let signature = hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b");
let signature = Signature::from_raw(signature);
@@ -644,9 +668,12 @@ mod test {
fn seeded_pair_should_work() {
let pair = Pair::from_seed(b"12345678901234567890123456789012");
let public = pair.public();
assert_eq!(public, Public::from_raw(
hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee")
));
assert_eq!(
public,
Public::from_raw(hex!(
"2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee"
))
);
let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000");
let signature = pair.sign(&message[..]);
println!("Correct signature: {:?}", signature);
+43 -10
View File
@@ -55,13 +55,34 @@ mod tests {
#[test]
fn test_h256() {
let tests = vec![
(Default::default(), "0x0000000000000000000000000000000000000000000000000000000000000000"),
(H256::from_low_u64_be(2), "0x0000000000000000000000000000000000000000000000000000000000000002"),
(H256::from_low_u64_be(15), "0x000000000000000000000000000000000000000000000000000000000000000f"),
(H256::from_low_u64_be(16), "0x0000000000000000000000000000000000000000000000000000000000000010"),
(H256::from_low_u64_be(1_000), "0x00000000000000000000000000000000000000000000000000000000000003e8"),
(H256::from_low_u64_be(100_000), "0x00000000000000000000000000000000000000000000000000000000000186a0"),
(H256::from_low_u64_be(u64::MAX), "0x000000000000000000000000000000000000000000000000ffffffffffffffff"),
(
Default::default(),
"0x0000000000000000000000000000000000000000000000000000000000000000",
),
(
H256::from_low_u64_be(2),
"0x0000000000000000000000000000000000000000000000000000000000000002",
),
(
H256::from_low_u64_be(15),
"0x000000000000000000000000000000000000000000000000000000000000000f",
),
(
H256::from_low_u64_be(16),
"0x0000000000000000000000000000000000000000000000000000000000000010",
),
(
H256::from_low_u64_be(1_000),
"0x00000000000000000000000000000000000000000000000000000000000003e8",
),
(
H256::from_low_u64_be(100_000),
"0x00000000000000000000000000000000000000000000000000000000000186a0",
),
(
H256::from_low_u64_be(u64::MAX),
"0x000000000000000000000000000000000000000000000000ffffffffffffffff",
),
];
for (number, expected) in tests {
@@ -72,9 +93,21 @@ mod tests {
#[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>(
"\"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());
+4 -4
View File
@@ -18,9 +18,9 @@
//! Substrate Blake2b Hasher implementation
pub mod blake2 {
use hash_db::Hasher;
use hash256_std_hasher::Hash256StdHasher;
use crate::hash::H256;
use hash256_std_hasher::Hash256StdHasher;
use hash_db::Hasher;
/// Concrete implementation of Hasher using Blake2b 256-bit hashes
#[derive(Debug)]
@@ -38,9 +38,9 @@ pub mod blake2 {
}
pub mod keccak {
use hash_db::Hasher;
use hash256_std_hasher::Hash256StdHasher;
use crate::hash::H256;
use hash256_std_hasher::Hash256StdHasher;
use hash_db::Hasher;
/// Concrete implementation of Hasher using Keccak 256-bit hashes
#[derive(Debug)]
+18 -8
View File
@@ -22,7 +22,9 @@ 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<R: AsBytesRef>(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) }
pub fn from<R: AsBytesRef>(d: &'a R) -> Self {
HexDisplay(d.as_bytes_ref())
}
}
impl<'a> sp_std::fmt::Display for HexDisplay<'a> {
@@ -60,15 +62,21 @@ pub trait AsBytesRef {
}
impl AsBytesRef for &[u8] {
fn as_bytes_ref(&self) -> &[u8] { self }
fn as_bytes_ref(&self) -> &[u8] {
self
}
}
impl AsBytesRef for [u8] {
fn as_bytes_ref(&self) -> &[u8] { &self }
fn as_bytes_ref(&self) -> &[u8] {
&self
}
}
impl AsBytesRef for sp_std::vec::Vec<u8> {
fn as_bytes_ref(&self) -> &[u8] { &self }
fn as_bytes_ref(&self) -> &[u8] {
&self
}
}
impl AsBytesRef for sp_storage::StorageKey {
@@ -85,9 +93,11 @@ macro_rules! impl_non_endians {
)* }
}
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; 65], [u8; 80], [u8; 96], [u8; 112], [u8; 128]);
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; 65], [u8; 80], [u8; 96], [u8; 112], [u8; 128]
);
/// Format into ASCII + # + hex, suitable for storage key preimages.
#[cfg(feature = "std")]
@@ -103,7 +113,7 @@ pub fn ascii_format(asciish: &[u8]) -> String {
latch = true;
}
r.push_str(&format!("{:02x}", *c));
}
},
}
}
r
+37 -29
View File
@@ -18,7 +18,6 @@
//! Shareable Substrate types.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
/// Initialize a key-value collection from array.
@@ -32,17 +31,16 @@ macro_rules! map {
);
}
use sp_runtime_interface::pass_by::{PassByEnum, PassByInner};
use sp_std::prelude::*;
use sp_std::ops::Deref;
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
#[doc(hidden)]
pub use codec::{Decode, Encode};
#[cfg(feature = "std")]
pub use serde;
#[doc(hidden)]
pub use codec::{Encode, Decode};
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_runtime_interface::pass_by::{PassByEnum, PassByInner};
use sp_std::{ops::Deref, prelude::*};
#[cfg(feature = "std")]
use std::borrow::Cow;
pub use sp_debug_derive::RuntimeDebug;
@@ -53,37 +51,39 @@ pub use impl_serde::serialize as bytes;
pub mod hashing;
#[cfg(feature = "full_crypto")]
pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256, keccak_256};
pub mod hexdisplay;
pub use hashing::{blake2_128, blake2_256, keccak_256, twox_128, twox_256, twox_64};
pub mod crypto;
pub mod hexdisplay;
pub mod u32_trait;
pub mod ed25519;
pub mod sr25519;
mod changes_trie;
pub mod ecdsa;
pub mod ed25519;
pub mod hash;
#[cfg(feature = "std")]
mod hasher;
pub mod offchain;
pub mod sandbox;
pub mod uint;
mod changes_trie;
pub mod sr25519;
pub mod testing;
#[cfg(feature = "std")]
pub mod traits;
pub mod testing;
pub mod uint;
pub use self::hash::{H160, H256, H512, convert_hash};
pub use self::uint::{U256, U512};
pub use self::{
hash::{convert_hash, H160, H256, H512},
uint::{U256, U512},
};
pub use changes_trie::{ChangesTrieConfiguration, ChangesTrieConfigurationRange};
#[cfg(feature = "full_crypto")]
pub use crypto::{DeriveJunction, Pair, Public};
pub use hash_db::Hasher;
#[cfg(feature = "std")]
pub use self::hasher::blake2::Blake2Hasher;
#[cfg(feature = "std")]
pub use self::hasher::keccak::KeccakHasher;
pub use hash_db::Hasher;
pub use sp_storage as storage;
@@ -117,14 +117,14 @@ impl ExecutionContext {
use ExecutionContext::*;
match self {
Importing | Syncing | BlockConstruction =>
offchain::Capabilities::none(),
Importing | Syncing | BlockConstruction => offchain::Capabilities::none(),
// Enable keystore, transaction pool and Offchain DB reads by default for offchain calls.
OffchainCall(None) => [
offchain::Capability::Keystore,
offchain::Capability::OffchainDbRead,
offchain::Capability::TransactionPool,
][..].into(),
][..]
.into(),
OffchainCall(Some((_, capabilities))) => *capabilities,
}
}
@@ -133,19 +133,25 @@ impl ExecutionContext {
/// Hex-serialized shim for `Vec<u8>`.
#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord))]
pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
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) }
fn from(s: Vec<u8>) -> Self {
Bytes(s)
}
}
impl From<OpaqueMetadata> for Bytes {
fn from(s: OpaqueMetadata) -> Self { Bytes(s.0) }
fn from(s: OpaqueMetadata) -> Self {
Bytes(s.0)
}
}
impl Deref for Bytes {
type Target = [u8];
fn deref(&self) -> &[u8] { &self.0[..] }
fn deref(&self) -> &[u8] {
&self.0[..]
}
}
impl codec::WrapperTypeEncode for Bytes {}
@@ -183,7 +189,9 @@ impl sp_std::ops::Deref for OpaqueMetadata {
}
/// Simple blob to hold a `PeerId` without committing to its format.
#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, PassByInner)]
#[derive(
Default, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, PassByInner,
)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct OpaquePeerId(pub Vec<u8>);
@@ -200,7 +208,7 @@ pub enum NativeOrEncoded<R> {
/// The native representation.
Native(R),
/// The encoded representation.
Encoded(Vec<u8>)
Encoded(Vec<u8>),
}
#[cfg(feature = "std")]
+67 -43
View File
@@ -17,10 +17,13 @@
//! Offchain workers types
use codec::{Encode, Decode};
use sp_std::{prelude::{Vec, Box}, convert::TryFrom};
use crate::{OpaquePeerId, RuntimeDebug};
use sp_runtime_interface::pass_by::{PassByCodec, PassByInner, PassByEnum};
use codec::{Decode, Encode};
use sp_runtime_interface::pass_by::{PassByCodec, PassByEnum, PassByInner};
use sp_std::{
convert::TryFrom,
prelude::{Box, Vec},
};
pub use crate::crypto::KeyTypeId;
@@ -30,7 +33,7 @@ pub mod storage;
pub mod testing;
/// Persistent storage prefix used by the Offchain Worker API when creating a DB key.
pub const STORAGE_PREFIX : &[u8] = b"storage";
pub const STORAGE_PREFIX: &[u8] = b"storage";
/// Offchain DB persistent (non-fork-aware) storage.
pub trait OffchainStorage: Clone + Send + Sync {
@@ -93,7 +96,9 @@ impl From<StorageKind> for u32 {
}
/// Opaque type for offchain http requests.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, Encode, Decode, PassByInner)]
#[derive(
Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, Encode, Decode, PassByInner,
)]
#[cfg_attr(feature = "std", derive(Hash))]
pub struct HttpRequestId(pub u16);
@@ -123,7 +128,7 @@ impl TryFrom<u32> for HttpError {
e if e == HttpError::DeadlineReached as u8 as u32 => Ok(HttpError::DeadlineReached),
e if e == HttpError::IoError as u8 as u32 => Ok(HttpError::IoError),
e if e == HttpError::Invalid as u8 as u32 => Ok(HttpError::Invalid),
_ => Err(())
_ => Err(()),
}
}
}
@@ -202,11 +207,15 @@ impl OpaqueMultiaddr {
}
/// Opaque timestamp type
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode)]
#[derive(
Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode,
)]
pub struct Timestamp(u64);
/// Duration type
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode)]
#[derive(
Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug, PassByInner, Encode, Decode,
)]
pub struct Duration(u64);
impl Duration {
@@ -290,11 +299,7 @@ impl Capabilities {
/// Those calls should be allowed to sign and submit transactions
/// and access offchain workers database (but read only!).
pub fn rich_offchain_call() -> Self {
[
Capability::TransactionPool,
Capability::Keystore,
Capability::OffchainDbRead,
][..].into()
[Capability::TransactionPool, Capability::Keystore, Capability::OffchainDbRead][..].into()
}
/// Check if particular capability is enabled.
@@ -345,12 +350,11 @@ pub trait Externalities: Send {
/// Returns an error if:
/// - No new request identifier could be allocated.
/// - The method or URI contain invalid characters.
///
fn http_request_start(
&mut self,
method: &str,
uri: &str,
meta: &[u8]
meta: &[u8],
) -> Result<HttpRequestId, ()>;
/// Append header to the request.
@@ -365,12 +369,11 @@ pub trait Externalities: Send {
///
/// An error doesn't poison the request, and you can continue as if the call had never been
/// made.
///
fn http_request_add_header(
&mut self,
request_id: HttpRequestId,
name: &str,
value: &str
value: &str,
) -> Result<(), ()>;
/// Write a chunk of request body.
@@ -387,12 +390,11 @@ pub trait Externalities: Send {
/// - The deadline is reached.
/// - An I/O error has happened, for example the remote has closed our
/// request. The request is then considered invalid.
///
fn http_request_write_body(
&mut self,
request_id: HttpRequestId,
chunk: &[u8],
deadline: Option<Timestamp>
deadline: Option<Timestamp>,
) -> Result<(), HttpError>;
/// Block and wait for the responses for given requests.
@@ -408,7 +410,7 @@ pub trait Externalities: Send {
fn http_response_wait(
&mut self,
ids: &[HttpRequestId],
deadline: Option<Timestamp>
deadline: Option<Timestamp>,
) -> Vec<HttpRequestStatus>;
/// Read all response headers.
@@ -420,10 +422,7 @@ pub trait Externalities: Send {
///
/// Returns an empty list if the identifier is unknown/invalid, hasn't
/// received a response, or has finished.
fn http_response_headers(
&mut self,
request_id: HttpRequestId
) -> Vec<(Vec<u8>, Vec<u8>)>;
fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec<u8>, Vec<u8>)>;
/// Read a chunk of body response to given buffer.
///
@@ -443,12 +442,11 @@ pub trait Externalities: Send {
/// - The deadline is reached.
/// - An I/O error has happened, for example the remote has closed our
/// request. The request is then considered invalid.
///
fn http_response_read_body(
&mut self,
request_id: HttpRequestId,
buffer: &mut [u8],
deadline: Option<Timestamp>
deadline: Option<Timestamp>,
) -> Result<usize, HttpError>;
/// Set the authorized nodes from runtime.
@@ -466,11 +464,11 @@ pub trait Externalities: Send {
impl<T: Externalities + ?Sized> Externalities for Box<T> {
fn is_validator(&self) -> bool {
(& **self).is_validator()
(&**self).is_validator()
}
fn network_state(&self) -> Result<OpaqueNetworkState, ()> {
(& **self).network_state()
(&**self).network_state()
}
fn timestamp(&mut self) -> Timestamp {
@@ -485,11 +483,21 @@ impl<T: Externalities + ?Sized> Externalities for Box<T> {
(&mut **self).random_seed()
}
fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result<HttpRequestId, ()> {
fn http_request_start(
&mut self,
method: &str,
uri: &str,
meta: &[u8],
) -> Result<HttpRequestId, ()> {
(&mut **self).http_request_start(method, uri, meta)
}
fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> {
fn http_request_add_header(
&mut self,
request_id: HttpRequestId,
name: &str,
value: &str,
) -> Result<(), ()> {
(&mut **self).http_request_add_header(request_id, name, value)
}
@@ -497,12 +505,16 @@ impl<T: Externalities + ?Sized> Externalities for Box<T> {
&mut self,
request_id: HttpRequestId,
chunk: &[u8],
deadline: Option<Timestamp>
deadline: Option<Timestamp>,
) -> Result<(), HttpError> {
(&mut **self).http_request_write_body(request_id, chunk, deadline)
}
fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option<Timestamp>) -> Vec<HttpRequestStatus> {
fn http_response_wait(
&mut self,
ids: &[HttpRequestId],
deadline: Option<Timestamp>,
) -> Vec<HttpRequestStatus> {
(&mut **self).http_response_wait(ids, deadline)
}
@@ -514,7 +526,7 @@ impl<T: Externalities + ?Sized> Externalities for Box<T> {
&mut self,
request_id: HttpRequestId,
buffer: &mut [u8],
deadline: Option<Timestamp>
deadline: Option<Timestamp>,
) -> Result<usize, HttpError> {
(&mut **self).http_response_read_body(request_id, buffer, deadline)
}
@@ -533,10 +545,7 @@ pub struct LimitedExternalities<T> {
impl<T> LimitedExternalities<T> {
/// Create new externalities limited to given `capabilities`.
pub fn new(capabilities: Capabilities, externalities: T) -> Self {
Self {
capabilities,
externalities,
}
Self { capabilities, externalities }
}
/// Check if given capability is allowed.
@@ -575,12 +584,22 @@ impl<T: Externalities> Externalities for LimitedExternalities<T> {
self.externalities.random_seed()
}
fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result<HttpRequestId, ()> {
fn http_request_start(
&mut self,
method: &str,
uri: &str,
meta: &[u8],
) -> Result<HttpRequestId, ()> {
self.check(Capability::Http, "http_request_start");
self.externalities.http_request_start(method, uri, meta)
}
fn http_request_add_header(&mut self, request_id: HttpRequestId, name: &str, value: &str) -> Result<(), ()> {
fn http_request_add_header(
&mut self,
request_id: HttpRequestId,
name: &str,
value: &str,
) -> Result<(), ()> {
self.check(Capability::Http, "http_request_add_header");
self.externalities.http_request_add_header(request_id, name, value)
}
@@ -589,13 +608,17 @@ impl<T: Externalities> Externalities for LimitedExternalities<T> {
&mut self,
request_id: HttpRequestId,
chunk: &[u8],
deadline: Option<Timestamp>
deadline: Option<Timestamp>,
) -> Result<(), HttpError> {
self.check(Capability::Http, "http_request_write_body");
self.externalities.http_request_write_body(request_id, chunk, deadline)
}
fn http_response_wait(&mut self, ids: &[HttpRequestId], deadline: Option<Timestamp>) -> Vec<HttpRequestStatus> {
fn http_response_wait(
&mut self,
ids: &[HttpRequestId],
deadline: Option<Timestamp>,
) -> Vec<HttpRequestStatus> {
self.check(Capability::Http, "http_response_wait");
self.externalities.http_response_wait(ids, deadline)
}
@@ -609,7 +632,7 @@ impl<T: Externalities> Externalities for LimitedExternalities<T> {
&mut self,
request_id: HttpRequestId,
buffer: &mut [u8],
deadline: Option<Timestamp>
deadline: Option<Timestamp>,
) -> Result<usize, HttpError> {
self.check(Capability::Http, "http_response_read_body");
self.externalities.http_response_read_body(request_id, buffer, deadline)
@@ -717,7 +740,8 @@ impl<T: DbExternalities> DbExternalities for LimitedExternalities<T> {
new_value: &[u8],
) -> bool {
self.check(Capability::OffchainDbWrite, "local_storage_compare_and_set");
self.externalities.local_storage_compare_and_set(kind, key, old_value, new_value)
self.externalities
.local_storage_compare_and_set(kind, key, old_value, new_value)
}
fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option<Vec<u8>> {
@@ -17,9 +17,11 @@
//! In-memory implementation of offchain workers database.
use std::collections::hash_map::{HashMap, Entry};
use crate::offchain::OffchainStorage;
use std::iter::Iterator;
use std::{
collections::hash_map::{Entry, HashMap},
iter::Iterator,
};
/// In-memory storage for offchain workers.
#[derive(Debug, Clone, Default)]
@@ -29,12 +31,12 @@ pub struct InMemOffchainStorage {
impl InMemOffchainStorage {
/// Consume the offchain storage and iterate over all key value pairs.
pub fn into_iter(self) -> impl Iterator<Item=(Vec<u8>,Vec<u8>)> {
pub fn into_iter(self) -> impl Iterator<Item = (Vec<u8>, Vec<u8>)> {
self.storage.into_iter()
}
/// Iterate over all key value pairs by reference.
pub fn iter(&self) -> impl Iterator<Item=(&Vec<u8>,&Vec<u8>)> {
pub fn iter(&self) -> impl Iterator<Item = (&Vec<u8>, &Vec<u8>)> {
self.storage.iter()
}
@@ -71,10 +73,13 @@ impl OffchainStorage for InMemOffchainStorage {
let key = prefix.iter().chain(key).cloned().collect();
match self.storage.entry(key) {
Entry::Vacant(entry) => if old_value.is_none() {
entry.insert(new_value.to_vec());
true
} else { false },
Entry::Vacant(entry) =>
if old_value.is_none() {
entry.insert(new_value.to_vec());
true
} else {
false
},
Entry::Occupied(ref mut entry) if Some(entry.get().as_slice()) == old_value => {
entry.insert(new_value.to_vec());
true
@@ -20,24 +20,18 @@
//! Namely all ExecutionExtensions that allow mocking
//! the extra APIs.
use crate::{
offchain::{
self, storage::InMemOffchainStorage, HttpError, HttpRequestId as RequestId,
HttpRequestStatus as RequestStatus, OffchainOverlayedChange, OffchainStorage,
OpaqueNetworkState, StorageKind, Timestamp, TransactionPool,
},
OpaquePeerId,
};
use std::{
collections::{BTreeMap, VecDeque},
sync::Arc,
};
use crate::OpaquePeerId;
use crate::offchain::{
self,
OffchainOverlayedChange,
storage::InMemOffchainStorage,
HttpError,
HttpRequestId as RequestId,
HttpRequestStatus as RequestStatus,
Timestamp,
StorageKind,
OpaqueNetworkState,
TransactionPool,
OffchainStorage,
};
use parking_lot::RwLock;
@@ -75,9 +69,7 @@ impl TestPersistentOffchainDB {
/// Create a new and empty offchain storage db for persistent items
pub fn new() -> Self {
Self {
persistent: Arc::new(RwLock::new(InMemOffchainStorage::default()))
}
Self { persistent: Arc::new(RwLock::new(InMemOffchainStorage::default())) }
}
/// Apply a set of off-chain changes directly to the test backend
@@ -88,7 +80,8 @@ impl TestPersistentOffchainDB {
let mut me = self.persistent.write();
for ((_prefix, key), value_operation) in changes {
match value_operation {
OffchainOverlayedChange::SetValue(val) => me.set(Self::PREFIX, key.as_slice(), val.as_slice()),
OffchainOverlayedChange::SetValue(val) =>
me.set(Self::PREFIX, key.as_slice(), val.as_slice()),
OffchainOverlayedChange::Remove => me.remove(Self::PREFIX, key.as_slice()),
}
}
@@ -124,7 +117,6 @@ impl OffchainStorage for TestPersistentOffchainDB {
}
}
/// Internal state of the externalities.
///
/// This can be used in tests to respond or assert stuff about interactions.
@@ -151,20 +143,17 @@ impl OffchainState {
id: u16,
expected: PendingRequest,
response: impl Into<Vec<u8>>,
response_headers: impl IntoIterator<Item=(String, String)>,
response_headers: impl IntoIterator<Item = (String, String)>,
) {
match self.requests.get_mut(&RequestId(id)) {
None => {
panic!("Missing pending request: {:?}.\n\nAll: {:?}", id, self.requests);
}
},
Some(req) => {
assert_eq!(
*req,
expected,
);
assert_eq!(*req, expected,);
req.response = Some(response.into());
req.response_headers = response_headers.into_iter().collect();
}
},
}
}
@@ -213,7 +202,9 @@ impl TestOffchainExt {
}
/// Create new `TestOffchainExt` and a reference to the internal state.
pub fn with_offchain_db(offchain_db: TestPersistentOffchainDB) -> (Self, Arc<RwLock<OffchainState>>) {
pub fn with_offchain_db(
offchain_db: TestPersistentOffchainDB,
) -> (Self, Arc<RwLock<OffchainState>>) {
let (ext, state) = Self::new();
ext.0.write().persistent_storage = offchain_db;
(ext, state)
@@ -226,10 +217,7 @@ impl offchain::Externalities for TestOffchainExt {
}
fn network_state(&self) -> Result<OpaqueNetworkState, ()> {
Ok(OpaqueNetworkState {
peer_id: Default::default(),
external_addresses: vec![],
})
Ok(OpaqueNetworkState { peer_id: Default::default(), external_addresses: vec![] })
}
fn timestamp(&mut self) -> Timestamp {
@@ -244,15 +232,23 @@ impl offchain::Externalities for TestOffchainExt {
self.0.read().seed
}
fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result<RequestId, ()> {
fn http_request_start(
&mut self,
method: &str,
uri: &str,
meta: &[u8],
) -> Result<RequestId, ()> {
let mut state = self.0.write();
let id = RequestId(state.requests.len() as u16);
state.requests.insert(id, PendingRequest {
method: method.into(),
uri: uri.into(),
meta: meta.into(),
..Default::default()
});
state.requests.insert(
id,
PendingRequest {
method: method.into(),
uri: uri.into(),
meta: meta.into(),
..Default::default()
},
);
Ok(id)
}
@@ -275,7 +271,7 @@ impl offchain::Externalities for TestOffchainExt {
&mut self,
request_id: RequestId,
chunk: &[u8],
_deadline: Option<Timestamp>
_deadline: Option<Timestamp>,
) -> Result<(), HttpError> {
let mut state = self.0.write();
@@ -302,12 +298,14 @@ impl offchain::Externalities for TestOffchainExt {
) -> Vec<RequestStatus> {
let state = self.0.read();
ids.iter().map(|id| match state.requests.get(id) {
Some(req) if req.response.is_none() =>
panic!("No `response` provided for request with id: {:?}", id),
None => RequestStatus::Invalid,
_ => RequestStatus::Finished(200),
}).collect()
ids.iter()
.map(|id| match state.requests.get(id) {
Some(req) if req.response.is_none() =>
panic!("No `response` provided for request with id: {:?}", id),
None => RequestStatus::Invalid,
_ => RequestStatus::Finished(200),
})
.collect()
}
fn http_response_headers(&mut self, request_id: RequestId) -> Vec<(Vec<u8>, Vec<u8>)> {
@@ -327,11 +325,12 @@ impl offchain::Externalities for TestOffchainExt {
&mut self,
request_id: RequestId,
buffer: &mut [u8],
_deadline: Option<Timestamp>
_deadline: Option<Timestamp>,
) -> Result<usize, HttpError> {
let mut state = self.0.write();
if let Some(req) = state.requests.get_mut(&request_id) {
let response = req.response
let response = req
.response
.as_mut()
.unwrap_or_else(|| panic!("No response provided for request: {:?}", request_id));
@@ -377,14 +376,14 @@ impl offchain::DbExternalities for TestOffchainExt {
kind: StorageKind,
key: &[u8],
old_value: Option<&[u8]>,
new_value: &[u8]
new_value: &[u8],
) -> bool {
let mut state = self.0.write();
match kind {
StorageKind::LOCAL => state.local_storage
.compare_and_set(b"", key, old_value, new_value),
StorageKind::PERSISTENT => state.persistent_storage
.compare_and_set(b"", key, old_value, new_value),
StorageKind::LOCAL =>
state.local_storage.compare_and_set(b"", key, old_value, new_value),
StorageKind::PERSISTENT =>
state.persistent_storage.compare_and_set(b"", key, old_value, new_value),
}
}
+18 -28
View File
@@ -17,17 +17,15 @@
//! Definition of a sandbox environment.
use codec::{Encode, Decode};
use codec::{Decode, Encode};
use sp_std::vec::Vec;
/// Error error that can be returned from host function.
#[derive(Encode, Decode)]
#[derive(crate::RuntimeDebug)]
#[derive(Encode, Decode, crate::RuntimeDebug)]
pub struct HostError;
/// Describes an entity to define or import into the environment.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[derive(crate::RuntimeDebug)]
#[derive(Clone, PartialEq, Eq, Encode, Decode, crate::RuntimeDebug)]
pub enum ExternEntity {
/// Function that is specified by an index in a default table of
/// a module that creates the sandbox.
@@ -44,8 +42,7 @@ pub enum ExternEntity {
///
/// Each entry has a two-level name and description of an entity
/// being defined.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[derive(crate::RuntimeDebug)]
#[derive(Clone, PartialEq, Eq, Encode, Decode, crate::RuntimeDebug)]
pub struct Entry {
/// Module name of which corresponding entity being defined.
pub module_name: Vec<u8>,
@@ -56,8 +53,7 @@ pub struct Entry {
}
/// Definition of runtime that could be used by sandboxed code.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[derive(crate::RuntimeDebug)]
#[derive(Clone, PartialEq, Eq, Encode, Decode, crate::RuntimeDebug)]
pub struct EnvironmentDefinition {
/// Vector of all entries in the environment definition.
pub entries: Vec<Entry>,
@@ -91,8 +87,8 @@ pub const ERR_EXECUTION: u32 = -3i32 as u32;
#[cfg(test)]
mod tests {
use super::*;
use std::fmt;
use codec::Codec;
use std::fmt;
fn roundtrip<S: Codec + PartialEq + fmt::Debug>(s: S) {
let encoded = s.encode();
@@ -101,28 +97,22 @@ mod tests {
#[test]
fn env_def_roundtrip() {
roundtrip(EnvironmentDefinition { entries: vec![] });
roundtrip(EnvironmentDefinition {
entries: vec![],
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"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),
},
],
entries: vec![Entry {
module_name: b"env"[..].into(),
field_name: b"abort"[..].into(),
entity: ExternEntity::Function(228),
}],
});
}
}
+92 -75
View File
@@ -21,34 +21,38 @@
//! Note: `CHAIN_CODE_LENGTH` must be equal to `crate::crypto::JUNCTION_ID_LEN`
//! for this to work.
// end::description[]
#[cfg(feature = "std")]
use crate::crypto::Ss58Codec;
#[cfg(feature = "full_crypto")]
use crate::crypto::{DeriveJunction, Infallible, Pair as TraitPair, SecretStringError};
#[cfg(feature = "std")]
use bip39::{Language, Mnemonic, MnemonicType};
#[cfg(feature = "full_crypto")]
use schnorrkel::{
derive::{ChainCode, Derivation, CHAIN_CODE_LENGTH},
signing_context, ExpansionMode, Keypair, MiniSecretKey, PublicKey, SecretKey,
};
#[cfg(feature = "full_crypto")]
use sp_std::vec::Vec;
#[cfg(feature = "full_crypto")]
use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey,
derive::{Derivation, ChainCode, CHAIN_CODE_LENGTH}
};
#[cfg(feature = "std")]
use std::convert::TryFrom;
#[cfg(feature = "std")]
use substrate_bip39::mini_secret_from_entropy;
#[cfg(feature = "std")]
use bip39::{Mnemonic, Language, MnemonicType};
#[cfg(feature = "full_crypto")]
use crate::crypto::{
Pair as TraitPair, DeriveJunction, Infallible, SecretStringError
};
#[cfg(feature = "std")]
use crate::crypto::Ss58Codec;
use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId};
use crate::hash::{H256, H512};
use codec::{Encode, Decode, MaxEncodedLen};
use crate::{
crypto::{
CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic,
UncheckedFrom,
},
hash::{H256, H512},
};
use codec::{Decode, Encode, MaxEncodedLen};
use sp_std::ops::Deref;
#[cfg(feature = "std")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "full_crypto")]
use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH};
#[cfg(feature = "std")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use sp_runtime_interface::pass_by::PassByInner;
// signing context
@@ -61,8 +65,7 @@ pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"sr25");
/// An Schnorrkel/Ristretto x25519 ("sr25519") public key.
#[cfg_attr(feature = "full_crypto", derive(Hash))]
#[derive(
PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner,
MaxEncodedLen,
PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Encode, Decode, Default, PassByInner, MaxEncodedLen,
)]
pub struct Public(pub [u8; 32]);
@@ -76,7 +79,7 @@ impl Clone for Pair {
Pair(schnorrkel::Keypair {
public: self.0.public,
secret: schnorrkel::SecretKey::from_bytes(&self.0.secret.to_bytes()[..])
.expect("key is always the correct size; qed")
.expect("key is always the correct size; qed"),
})
}
}
@@ -176,14 +179,20 @@ impl sp_std::fmt::Debug for Public {
#[cfg(feature = "std")]
impl Serialize for Public {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_ss58check())
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for Public {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Public::from_ss58check(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))
}
@@ -211,14 +220,20 @@ impl sp_std::convert::TryFrom<&[u8]> for Signature {
#[cfg(feature = "std")]
impl Serialize for Signature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&hex::encode(self))
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for Signature {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let signature_hex = hex::decode(&String::deserialize(deserializer)?)
.map_err(|e| de::Error::custom(format!("{:?}", e)))?;
Signature::try_from(signature_hex.as_ref())
@@ -350,7 +365,7 @@ impl Derive for Public {
///
/// `None` if there are any hard junctions in there.
#[cfg(feature = "std")]
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self, path: Iter) -> Option<Public> {
fn derive<Iter: Iterator<Item = DeriveJunction>>(&self, path: Iter) -> Option<Public> {
let mut acc = PublicKey::from_bytes(self.as_ref()).ok()?;
for j in path {
match j {
@@ -471,8 +486,7 @@ impl TraitPair for Pair {
///
/// A MiniSecretKey is literally what Ed25519 calls a SecretKey, which is just 32 random bytes.
fn from_seed(seed: &Seed) -> Pair {
Self::from_seed_slice(&seed[..])
.expect("32 bytes can always build a key; qed")
Self::from_seed_slice(&seed[..]).expect("32 bytes can always build a key; qed")
}
/// Get the public key.
@@ -488,21 +502,17 @@ impl TraitPair for Pair {
/// You should never need to use this; generate(), generate_with_phrase(), from_phrase()
fn from_seed_slice(seed: &[u8]) -> Result<Pair, SecretStringError> {
match seed.len() {
MINI_SECRET_KEY_LENGTH => {
Ok(Pair(
MiniSecretKey::from_bytes(seed)
.map_err(|_| SecretStringError::InvalidSeed)?
.expand_to_keypair(ExpansionMode::Ed25519)
))
}
SECRET_KEY_LENGTH => {
Ok(Pair(
SecretKey::from_bytes(seed)
.map_err(|_| SecretStringError::InvalidSeed)?
.to_keypair()
))
}
_ => Err(SecretStringError::InvalidSeedLength)
MINI_SECRET_KEY_LENGTH => Ok(Pair(
MiniSecretKey::from_bytes(seed)
.map_err(|_| SecretStringError::InvalidSeed)?
.expand_to_keypair(ExpansionMode::Ed25519),
)),
SECRET_KEY_LENGTH => Ok(Pair(
SecretKey::from_bytes(seed)
.map_err(|_| SecretStringError::InvalidSeed)?
.to_keypair(),
)),
_ => Err(SecretStringError::InvalidSeedLength),
}
}
#[cfg(feature = "std")]
@@ -511,20 +521,20 @@ impl TraitPair for Pair {
let phrase = mnemonic.phrase();
let (pair, seed) = Self::from_phrase(phrase, password)
.expect("All phrases generated by Mnemonic are valid; qed");
(
pair,
phrase.to_owned(),
seed,
)
(pair, phrase.to_owned(), seed)
}
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
fn from_phrase(
phrase: &str,
password: Option<&str>,
) -> Result<(Pair, Seed), SecretStringError> {
Mnemonic::from_phrase(phrase, Language::English)
.map_err(|_| SecretStringError::InvalidPhrase)
.map(|m| Self::from_entropy(m.entropy(), password))
}
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self,
fn derive<Iter: Iterator<Item = DeriveJunction>>(
&self,
path: Iter,
seed: Option<Seed>,
) -> Result<(Pair, Option<Seed>), Self::DeriveError> {
@@ -532,17 +542,22 @@ impl TraitPair for Pair {
if let Ok(msk) = MiniSecretKey::from_bytes(&s) {
if msk.expand(ExpansionMode::Ed25519) == self.0.secret {
Some(msk)
} else { None }
} else { None }
} else { None };
} else {
None
}
} else {
None
}
} else {
None
};
let init = self.0.secret.clone();
let (result, seed) = path.fold((init, seed), |(acc, acc_seed), j| match (j, acc_seed) {
(DeriveJunction::Soft(cc), _) =>
(acc.derived_key_simple(ChainCode(cc), &[]).0, None),
(DeriveJunction::Soft(cc), _) => (acc.derived_key_simple(ChainCode(cc), &[]).0, None),
(DeriveJunction::Hard(cc), maybe_seed) => {
let seed = derive_hard_junction(&acc, &cc);
(seed.expand(ExpansionMode::Ed25519), maybe_seed.map(|_| seed))
}
},
});
Ok((Self(result.into()), seed.map(|s| MiniSecretKey::to_bytes(&s))))
}
@@ -596,9 +611,9 @@ impl Pair {
// Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets
// that have not been upgraded and those that have.
match PublicKey::from_bytes(pubkey.as_ref()) {
Ok(pk) => pk.verify_simple_preaudit_deprecated(
SIGNING_CTX, message.as_ref(), &sig.0[..],
).is_ok(),
Ok(pk) => pk
.verify_simple_preaudit_deprecated(SIGNING_CTX, message.as_ref(), &sig.0[..])
.is_ok(),
Err(_) => false,
}
}
@@ -642,20 +657,16 @@ pub fn verify_batch(
for signature in signatures {
match schnorrkel::Signature::from_bytes(signature.as_ref()) {
Ok(s) => sr_signatures.push(s),
Err(_) => return false
Err(_) => return false,
};
}
let mut messages: Vec<merlin::Transcript> = messages.into_iter().map(
|msg| signing_context(SIGNING_CTX).bytes(msg)
).collect();
let mut messages: Vec<merlin::Transcript> = messages
.into_iter()
.map(|msg| signing_context(SIGNING_CTX).bytes(msg))
.collect();
schnorrkel::verify_batch(
&mut messages,
&sr_signatures,
&sr_pub_keys,
true,
).is_ok()
schnorrkel::verify_batch(&mut messages, &sr_signatures, &sr_pub_keys, true).is_ok()
}
#[cfg(test)]
@@ -685,7 +696,9 @@ mod compatibility_test {
#[test]
fn verify_known_old_message_should_work() {
let public = Public::from_raw(hex!("b4bfa1f7a5166695eb75299fd1c4c03ea212871c342f2c5dfea0902b2c246918"));
let public = Public::from_raw(hex!(
"b4bfa1f7a5166695eb75299fd1c4c03ea212871c342f2c5dfea0902b2c246918"
));
// signature generated by the 1.1 version with the same ^^ public key.
let signature = Signature::from_raw(hex!(
"5a9755f069939f45d96aaf125cf5ce7ba1db998686f87f2fb3cbdea922078741a73891ba265f70c31436e18a9acd14d189d73c12317ab6c313285cd938453202"
@@ -699,7 +712,7 @@ mod compatibility_test {
#[cfg(test)]
mod test {
use super::*;
use crate::crypto::{Ss58Codec, DEV_PHRASE, DEV_ADDRESS};
use crate::crypto::{Ss58Codec, DEV_ADDRESS, DEV_PHRASE};
use hex_literal::hex;
use serde_json;
@@ -707,10 +720,14 @@ mod test {
fn default_phrase_should_be_used() {
assert_eq!(
Pair::from_string("//Alice///password", None).unwrap().public(),
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(),
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password"))
.unwrap()
.public(),
);
assert_eq!(
Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).as_ref().map(Pair::public),
Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None)
.as_ref()
.map(Pair::public),
Pair::from_string("/Alice", None).as_ref().map(Pair::public)
);
}
@@ -856,9 +873,9 @@ mod test {
// The values in this test case are compared to the output of `node-test.js` in schnorrkel-js.
//
// This is to make sure that the wasm library is compatible.
let pk = Pair::from_seed(
&hex!("0000000000000000000000000000000000000000000000000000000000000000")
);
let pk = Pair::from_seed(&hex!(
"0000000000000000000000000000000000000000000000000000000000000000"
));
let public = pk.public();
let js_signature = Signature::from_raw(hex!(
"28a854d54903e056f89581c691c1f7d2ff39f8f896c9e9c22475e60902cc2b3547199e0e91fa32902028f2ca2355e8cdd16cfe19ba5e8b658c94aa80f3b81a00"
+5 -1
View File
@@ -162,7 +162,11 @@ impl crate::traits::SpawnNamed for TaskExecutor {
#[cfg(feature = "std")]
impl crate::traits::SpawnEssentialNamed for TaskExecutor {
fn spawn_essential_blocking(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) {
fn spawn_essential_blocking(
&self,
_: &'static str,
future: futures::future::BoxFuture<'static, ()>,
) {
self.0.spawn_ok(future);
}
fn spawn_essential(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) {
+11 -7
View File
@@ -99,11 +99,7 @@ impl<'a> RuntimeCode<'a> {
///
/// This is only useful for tests that don't want to execute any code.
pub fn empty() -> Self {
Self {
code_fetcher: &NoneFetchRuntimeCode,
hash: Vec::new(),
heap_pages: None,
}
Self { code_fetcher: &NoneFetchRuntimeCode, hash: Vec::new(), heap_pages: None }
}
}
@@ -225,7 +221,11 @@ pub trait SpawnEssentialNamed: Clone + Send + Sync {
/// Spawn the given blocking future.
///
/// The given `name` is used to identify the future in tracing.
fn spawn_essential_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>);
fn spawn_essential_blocking(
&self,
name: &'static str,
future: futures::future::BoxFuture<'static, ()>,
);
/// Spawn the given non-blocking future.
///
/// The given `name` is used to identify the future in tracing.
@@ -233,7 +233,11 @@ pub trait SpawnEssentialNamed: Clone + Send + Sync {
}
impl SpawnEssentialNamed for Box<dyn SpawnEssentialNamed> {
fn spawn_essential_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>) {
fn spawn_essential_blocking(
&self,
name: &'static str,
future: futures::future::BoxFuture<'static, ()>,
) {
(**self).spawn_essential_blocking(name, future)
}
+436 -110
View File
@@ -24,221 +24,547 @@ pub trait Value {
}
/// Type representing the value 0 for the `Value` trait.
pub struct _0; impl Value for _0 { const VALUE: u32 = 0; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
pub struct _16;
impl Value for _16 {
const VALUE: u32 = 16;
}
/// Type representing the value 17 for the `Value` trait.
pub struct _17; impl Value for _17 { const VALUE: u32 = 17; }
pub struct _17;
impl Value for _17 {
const VALUE: u32 = 17;
}
/// Type representing the value 18 for the `Value` trait.
pub struct _18; impl Value for _18 { const VALUE: u32 = 18; }
pub struct _18;
impl Value for _18 {
const VALUE: u32 = 18;
}
/// Type representing the value 19 for the `Value` trait.
pub struct _19; impl Value for _19 { const VALUE: u32 = 19; }
pub struct _19;
impl Value for _19 {
const VALUE: u32 = 19;
}
/// Type representing the value 20 for the `Value` trait.
pub struct _20; impl Value for _20 { const VALUE: u32 = 20; }
pub struct _20;
impl Value for _20 {
const VALUE: u32 = 20;
}
/// Type representing the value 21 for the `Value` trait.
pub struct _21; impl Value for _21 { const VALUE: u32 = 21; }
pub struct _21;
impl Value for _21 {
const VALUE: u32 = 21;
}
/// Type representing the value 22 for the `Value` trait.
pub struct _22; impl Value for _22 { const VALUE: u32 = 22; }
pub struct _22;
impl Value for _22 {
const VALUE: u32 = 22;
}
/// Type representing the value 23 for the `Value` trait.
pub struct _23; impl Value for _23 { const VALUE: u32 = 23; }
pub struct _23;
impl Value for _23 {
const VALUE: u32 = 23;
}
/// Type representing the value 24 for the `Value` trait.
pub struct _24; impl Value for _24 { const VALUE: u32 = 24; }
pub struct _24;
impl Value for _24 {
const VALUE: u32 = 24;
}
/// Type representing the value 25 for the `Value` trait.
pub struct _25; impl Value for _25 { const VALUE: u32 = 25; }
pub struct _25;
impl Value for _25 {
const VALUE: u32 = 25;
}
/// Type representing the value 26 for the `Value` trait.
pub struct _26; impl Value for _26 { const VALUE: u32 = 26; }
pub struct _26;
impl Value for _26 {
const VALUE: u32 = 26;
}
/// Type representing the value 27 for the `Value` trait.
pub struct _27; impl Value for _27 { const VALUE: u32 = 27; }
pub struct _27;
impl Value for _27 {
const VALUE: u32 = 27;
}
/// Type representing the value 28 for the `Value` trait.
pub struct _28; impl Value for _28 { const VALUE: u32 = 28; }
pub struct _28;
impl Value for _28 {
const VALUE: u32 = 28;
}
/// Type representing the value 29 for the `Value` trait.
pub struct _29; impl Value for _29 { const VALUE: u32 = 29; }
pub struct _29;
impl Value for _29 {
const VALUE: u32 = 29;
}
/// Type representing the value 30 for the `Value` trait.
pub struct _30; impl Value for _30 { const VALUE: u32 = 30; }
pub struct _30;
impl Value for _30 {
const VALUE: u32 = 30;
}
/// Type representing the value 31 for the `Value` trait.
pub struct _31; impl Value for _31 { const VALUE: u32 = 31; }
pub struct _31;
impl Value for _31 {
const VALUE: u32 = 31;
}
/// Type representing the value 32 for the `Value` trait.
pub struct _32; impl Value for _32 { const VALUE: u32 = 32; }
pub struct _32;
impl Value for _32 {
const VALUE: u32 = 32;
}
/// Type representing the value 33 for the `Value` trait.
pub struct _33; impl Value for _33 { const VALUE: u32 = 33; }
pub struct _33;
impl Value for _33 {
const VALUE: u32 = 33;
}
/// Type representing the value 34 for the `Value` trait.
pub struct _34; impl Value for _34 { const VALUE: u32 = 34; }
pub struct _34;
impl Value for _34 {
const VALUE: u32 = 34;
}
/// Type representing the value 35 for the `Value` trait.
pub struct _35; impl Value for _35 { const VALUE: u32 = 35; }
pub struct _35;
impl Value for _35 {
const VALUE: u32 = 35;
}
/// Type representing the value 36 for the `Value` trait.
pub struct _36; impl Value for _36 { const VALUE: u32 = 36; }
pub struct _36;
impl Value for _36 {
const VALUE: u32 = 36;
}
/// Type representing the value 37 for the `Value` trait.
pub struct _37; impl Value for _37 { const VALUE: u32 = 37; }
pub struct _37;
impl Value for _37 {
const VALUE: u32 = 37;
}
/// Type representing the value 38 for the `Value` trait.
pub struct _38; impl Value for _38 { const VALUE: u32 = 38; }
pub struct _38;
impl Value for _38 {
const VALUE: u32 = 38;
}
/// Type representing the value 39 for the `Value` trait.
pub struct _39; impl Value for _39 { const VALUE: u32 = 39; }
pub struct _39;
impl Value for _39 {
const VALUE: u32 = 39;
}
/// Type representing the value 40 for the `Value` trait.
pub struct _40; impl Value for _40 { const VALUE: u32 = 40; }
pub struct _40;
impl Value for _40 {
const VALUE: u32 = 40;
}
/// Type representing the value 41 for the `Value` trait.
pub struct _41; impl Value for _41 { const VALUE: u32 = 41; }
pub struct _41;
impl Value for _41 {
const VALUE: u32 = 41;
}
/// Type representing the value 42 for the `Value` trait.
pub struct _42; impl Value for _42 { const VALUE: u32 = 42; }
pub struct _42;
impl Value for _42 {
const VALUE: u32 = 42;
}
/// Type representing the value 43 for the `Value` trait.
pub struct _43; impl Value for _43 { const VALUE: u32 = 43; }
pub struct _43;
impl Value for _43 {
const VALUE: u32 = 43;
}
/// Type representing the value 44 for the `Value` trait.
pub struct _44; impl Value for _44 { const VALUE: u32 = 44; }
pub struct _44;
impl Value for _44 {
const VALUE: u32 = 44;
}
/// Type representing the value 45 for the `Value` trait.
pub struct _45; impl Value for _45 { const VALUE: u32 = 45; }
pub struct _45;
impl Value for _45 {
const VALUE: u32 = 45;
}
/// Type representing the value 46 for the `Value` trait.
pub struct _46; impl Value for _46 { const VALUE: u32 = 46; }
pub struct _46;
impl Value for _46 {
const VALUE: u32 = 46;
}
/// Type representing the value 47 for the `Value` trait.
pub struct _47; impl Value for _47 { const VALUE: u32 = 47; }
pub struct _47;
impl Value for _47 {
const VALUE: u32 = 47;
}
/// Type representing the value 48 for the `Value` trait.
pub struct _48; impl Value for _48 { const VALUE: u32 = 48; }
pub struct _48;
impl Value for _48 {
const VALUE: u32 = 48;
}
/// Type representing the value 49 for the `Value` trait.
pub struct _49; impl Value for _49 { const VALUE: u32 = 49; }
pub struct _49;
impl Value for _49 {
const VALUE: u32 = 49;
}
/// Type representing the value 50 for the `Value` trait.
pub struct _50; impl Value for _50 { const VALUE: u32 = 50; }
pub struct _50;
impl Value for _50 {
const VALUE: u32 = 50;
}
/// Type representing the value 51 for the `Value` trait.
pub struct _51; impl Value for _51 { const VALUE: u32 = 51; }
pub struct _51;
impl Value for _51 {
const VALUE: u32 = 51;
}
/// Type representing the value 52 for the `Value` trait.
pub struct _52; impl Value for _52 { const VALUE: u32 = 52; }
pub struct _52;
impl Value for _52 {
const VALUE: u32 = 52;
}
/// Type representing the value 53 for the `Value` trait.
pub struct _53; impl Value for _53 { const VALUE: u32 = 53; }
pub struct _53;
impl Value for _53 {
const VALUE: u32 = 53;
}
/// Type representing the value 54 for the `Value` trait.
pub struct _54; impl Value for _54 { const VALUE: u32 = 54; }
pub struct _54;
impl Value for _54 {
const VALUE: u32 = 54;
}
/// Type representing the value 55 for the `Value` trait.
pub struct _55; impl Value for _55 { const VALUE: u32 = 55; }
pub struct _55;
impl Value for _55 {
const VALUE: u32 = 55;
}
/// Type representing the value 56 for the `Value` trait.
pub struct _56; impl Value for _56 { const VALUE: u32 = 56; }
pub struct _56;
impl Value for _56 {
const VALUE: u32 = 56;
}
/// Type representing the value 57 for the `Value` trait.
pub struct _57; impl Value for _57 { const VALUE: u32 = 57; }
pub struct _57;
impl Value for _57 {
const VALUE: u32 = 57;
}
/// Type representing the value 58 for the `Value` trait.
pub struct _58; impl Value for _58 { const VALUE: u32 = 58; }
pub struct _58;
impl Value for _58 {
const VALUE: u32 = 58;
}
/// Type representing the value 59 for the `Value` trait.
pub struct _59; impl Value for _59 { const VALUE: u32 = 59; }
pub struct _59;
impl Value for _59 {
const VALUE: u32 = 59;
}
/// Type representing the value 60 for the `Value` trait.
pub struct _60; impl Value for _60 { const VALUE: u32 = 60; }
pub struct _60;
impl Value for _60 {
const VALUE: u32 = 60;
}
/// Type representing the value 61 for the `Value` trait.
pub struct _61; impl Value for _61 { const VALUE: u32 = 61; }
pub struct _61;
impl Value for _61 {
const VALUE: u32 = 61;
}
/// Type representing the value 62 for the `Value` trait.
pub struct _62; impl Value for _62 { const VALUE: u32 = 62; }
pub struct _62;
impl Value for _62 {
const VALUE: u32 = 62;
}
/// Type representing the value 63 for the `Value` trait.
pub struct _63; impl Value for _63 { const VALUE: u32 = 63; }
pub struct _63;
impl Value for _63 {
const VALUE: u32 = 63;
}
/// Type representing the value 64 for the `Value` trait.
pub struct _64; impl Value for _64 { const VALUE: u32 = 64; }
pub struct _64;
impl Value for _64 {
const VALUE: u32 = 64;
}
/// Type representing the value 65 for the `Value` trait.
pub struct _65; impl Value for _65 { const VALUE: u32 = 65; }
pub struct _65;
impl Value for _65 {
const VALUE: u32 = 65;
}
/// Type representing the value 66 for the `Value` trait.
pub struct _66; impl Value for _66 { const VALUE: u32 = 66; }
pub struct _66;
impl Value for _66 {
const VALUE: u32 = 66;
}
/// Type representing the value 67 for the `Value` trait.
pub struct _67; impl Value for _67 { const VALUE: u32 = 67; }
pub struct _67;
impl Value for _67 {
const VALUE: u32 = 67;
}
/// Type representing the value 68 for the `Value` trait.
pub struct _68; impl Value for _68 { const VALUE: u32 = 68; }
pub struct _68;
impl Value for _68 {
const VALUE: u32 = 68;
}
/// Type representing the value 69 for the `Value` trait.
pub struct _69; impl Value for _69 { const VALUE: u32 = 69; }
pub struct _69;
impl Value for _69 {
const VALUE: u32 = 69;
}
/// Type representing the value 70 for the `Value` trait.
pub struct _70; impl Value for _70 { const VALUE: u32 = 70; }
pub struct _70;
impl Value for _70 {
const VALUE: u32 = 70;
}
/// Type representing the value 71 for the `Value` trait.
pub struct _71; impl Value for _71 { const VALUE: u32 = 71; }
pub struct _71;
impl Value for _71 {
const VALUE: u32 = 71;
}
/// Type representing the value 72 for the `Value` trait.
pub struct _72; impl Value for _72 { const VALUE: u32 = 72; }
pub struct _72;
impl Value for _72 {
const VALUE: u32 = 72;
}
/// Type representing the value 73 for the `Value` trait.
pub struct _73; impl Value for _73 { const VALUE: u32 = 73; }
pub struct _73;
impl Value for _73 {
const VALUE: u32 = 73;
}
/// Type representing the value 74 for the `Value` trait.
pub struct _74; impl Value for _74 { const VALUE: u32 = 74; }
pub struct _74;
impl Value for _74 {
const VALUE: u32 = 74;
}
/// Type representing the value 75 for the `Value` trait.
pub struct _75; impl Value for _75 { const VALUE: u32 = 75; }
pub struct _75;
impl Value for _75 {
const VALUE: u32 = 75;
}
/// Type representing the value 76 for the `Value` trait.
pub struct _76; impl Value for _76 { const VALUE: u32 = 76; }
pub struct _76;
impl Value for _76 {
const VALUE: u32 = 76;
}
/// Type representing the value 77 for the `Value` trait.
pub struct _77; impl Value for _77 { const VALUE: u32 = 77; }
pub struct _77;
impl Value for _77 {
const VALUE: u32 = 77;
}
/// Type representing the value 78 for the `Value` trait.
pub struct _78; impl Value for _78 { const VALUE: u32 = 78; }
pub struct _78;
impl Value for _78 {
const VALUE: u32 = 78;
}
/// Type representing the value 79 for the `Value` trait.
pub struct _79; impl Value for _79 { const VALUE: u32 = 79; }
pub struct _79;
impl Value for _79 {
const VALUE: u32 = 79;
}
/// Type representing the value 80 for the `Value` trait.
pub struct _80; impl Value for _80 { const VALUE: u32 = 80; }
pub struct _80;
impl Value for _80 {
const VALUE: u32 = 80;
}
/// Type representing the value 81 for the `Value` trait.
pub struct _81; impl Value for _81 { const VALUE: u32 = 81; }
pub struct _81;
impl Value for _81 {
const VALUE: u32 = 81;
}
/// Type representing the value 82 for the `Value` trait.
pub struct _82; impl Value for _82 { const VALUE: u32 = 82; }
pub struct _82;
impl Value for _82 {
const VALUE: u32 = 82;
}
/// Type representing the value 83 for the `Value` trait.
pub struct _83; impl Value for _83 { const VALUE: u32 = 83; }
pub struct _83;
impl Value for _83 {
const VALUE: u32 = 83;
}
/// Type representing the value 84 for the `Value` trait.
pub struct _84; impl Value for _84 { const VALUE: u32 = 84; }
pub struct _84;
impl Value for _84 {
const VALUE: u32 = 84;
}
/// Type representing the value 85 for the `Value` trait.
pub struct _85; impl Value for _85 { const VALUE: u32 = 85; }
pub struct _85;
impl Value for _85 {
const VALUE: u32 = 85;
}
/// Type representing the value 86 for the `Value` trait.
pub struct _86; impl Value for _86 { const VALUE: u32 = 86; }
pub struct _86;
impl Value for _86 {
const VALUE: u32 = 86;
}
/// Type representing the value 87 for the `Value` trait.
pub struct _87; impl Value for _87 { const VALUE: u32 = 87; }
pub struct _87;
impl Value for _87 {
const VALUE: u32 = 87;
}
/// Type representing the value 88 for the `Value` trait.
pub struct _88; impl Value for _88 { const VALUE: u32 = 88; }
pub struct _88;
impl Value for _88 {
const VALUE: u32 = 88;
}
/// Type representing the value 89 for the `Value` trait.
pub struct _89; impl Value for _89 { const VALUE: u32 = 89; }
pub struct _89;
impl Value for _89 {
const VALUE: u32 = 89;
}
/// Type representing the value 90 for the `Value` trait.
pub struct _90; impl Value for _90 { const VALUE: u32 = 90; }
pub struct _90;
impl Value for _90 {
const VALUE: u32 = 90;
}
/// Type representing the value 91 for the `Value` trait.
pub struct _91; impl Value for _91 { const VALUE: u32 = 91; }
pub struct _91;
impl Value for _91 {
const VALUE: u32 = 91;
}
/// Type representing the value 92 for the `Value` trait.
pub struct _92; impl Value for _92 { const VALUE: u32 = 92; }
pub struct _92;
impl Value for _92 {
const VALUE: u32 = 92;
}
/// Type representing the value 93 for the `Value` trait.
pub struct _93; impl Value for _93 { const VALUE: u32 = 93; }
pub struct _93;
impl Value for _93 {
const VALUE: u32 = 93;
}
/// Type representing the value 94 for the `Value` trait.
pub struct _94; impl Value for _94 { const VALUE: u32 = 94; }
pub struct _94;
impl Value for _94 {
const VALUE: u32 = 94;
}
/// Type representing the value 95 for the `Value` trait.
pub struct _95; impl Value for _95 { const VALUE: u32 = 95; }
pub struct _95;
impl Value for _95 {
const VALUE: u32 = 95;
}
/// Type representing the value 96 for the `Value` trait.
pub struct _96; impl Value for _96 { const VALUE: u32 = 96; }
pub struct _96;
impl Value for _96 {
const VALUE: u32 = 96;
}
/// Type representing the value 97 for the `Value` trait.
pub struct _97; impl Value for _97 { const VALUE: u32 = 97; }
pub struct _97;
impl Value for _97 {
const VALUE: u32 = 97;
}
/// Type representing the value 98 for the `Value` trait.
pub struct _98; impl Value for _98 { const VALUE: u32 = 98; }
pub struct _98;
impl Value for _98 {
const VALUE: u32 = 98;
}
/// Type representing the value 99 for the `Value` trait.
pub struct _99; impl Value for _99 { const VALUE: u32 = 99; }
pub struct _99;
impl Value for _99 {
const VALUE: u32 = 99;
}
/// Type representing the value 100 for the `Value` trait.
pub struct _100; impl Value for _100 { const VALUE: u32 = 100; }
pub struct _100;
impl Value for _100 {
const VALUE: u32 = 100;
}
/// Type representing the value 112 for the `Value` trait.
pub struct _112; impl Value for _112 { const VALUE: u32 = 112; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
pub struct _512;
impl Value for _512 {
const VALUE: u32 = 512;
}
+20 -27
View File
@@ -22,7 +22,7 @@ pub use primitive_types::{U256, U512};
#[cfg(test)]
mod tests {
use super::*;
use codec::{Encode, Decode};
use codec::{Decode, Encode};
use sp_serializer as ser;
macro_rules! test {
@@ -55,34 +55,27 @@ mod tests {
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_u256_codec() {
let res1 = vec![120, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0];
let res2 = vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
let res1 = vec![
120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
];
let res2 = vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
];
assert_eq!(
U256::from(120).encode(),
res1);
assert_eq!(
U256::max_value().encode(),
res2);
assert_eq!(
U256::decode(&mut &res1[..]),
Ok(U256::from(120)));
assert_eq!(
U256::decode(&mut &res2[..]),
Ok(U256::max_value()));
assert_eq!(U256::from(120).encode(), res1);
assert_eq!(U256::max_value().encode(), res2);
assert_eq!(U256::decode(&mut &res1[..]), Ok(U256::from(120)));
assert_eq!(U256::decode(&mut &res2[..]), Ok(U256::max_value()));
}
#[test]
@@ -91,10 +84,10 @@ mod tests {
ser::to_string_pretty(&!U256::zero()),
"\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\""
);
assert!(
ser::from_str::<U256>("\"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"")
.unwrap_err()
.is_data()
);
assert!(ser::from_str::<U256>(
"\"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\""
)
.unwrap_err()
.is_data());
}
}