mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 00:58:02 +00:00
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:
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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.",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
}],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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, ()>) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user