mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 11:27:58 +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,7 +17,10 @@
|
||||
|
||||
//! Provides some utilities to define a piecewise linear function.
|
||||
|
||||
use crate::{Perbill, traits::{AtLeast32BitUnsigned, SaturatedConversion}};
|
||||
use crate::{
|
||||
traits::{AtLeast32BitUnsigned, SaturatedConversion},
|
||||
Perbill,
|
||||
};
|
||||
use core::ops::Sub;
|
||||
|
||||
/// Piecewise Linear function in [0, 1] -> [0, 1].
|
||||
@@ -29,14 +32,15 @@ pub struct PiecewiseLinear<'a> {
|
||||
pub maximum: Perbill,
|
||||
}
|
||||
|
||||
fn abs_sub<N: Ord + Sub<Output=N> + Clone>(a: N, b: N) -> N where {
|
||||
fn abs_sub<N: Ord + Sub<Output = N> + Clone>(a: N, b: N) -> N where {
|
||||
a.clone().max(b.clone()) - a.min(b)
|
||||
}
|
||||
|
||||
impl<'a> PiecewiseLinear<'a> {
|
||||
/// Compute `f(n/d)*d` with `n <= d`. This is useful to avoid loss of precision.
|
||||
pub fn calculate_for_fraction_times_denominator<N>(&self, n: N, d: N) -> N where
|
||||
N: AtLeast32BitUnsigned + Clone
|
||||
pub fn calculate_for_fraction_times_denominator<N>(&self, n: N, d: N) -> N
|
||||
where
|
||||
N: AtLeast32BitUnsigned + Clone,
|
||||
{
|
||||
let n = n.min(d.clone());
|
||||
|
||||
@@ -44,8 +48,7 @@ impl<'a> PiecewiseLinear<'a> {
|
||||
return N::zero()
|
||||
}
|
||||
|
||||
let next_point_index = self.points.iter()
|
||||
.position(|p| n < p.0 * d.clone());
|
||||
let next_point_index = self.points.iter().position(|p| n < p.0 * d.clone());
|
||||
|
||||
let (prev, next) = if let Some(next_point_index) = next_point_index {
|
||||
if let Some(previous_point_index) = next_point_index.checked_sub(1) {
|
||||
@@ -80,7 +83,8 @@ impl<'a> PiecewiseLinear<'a> {
|
||||
// This is guaranteed not to overflow on whatever values nor lose precision.
|
||||
// `q` must be superior to zero.
|
||||
fn multiply_by_rational_saturating<N>(value: N, p: u32, q: u32) -> N
|
||||
where N: AtLeast32BitUnsigned + Clone
|
||||
where
|
||||
N: AtLeast32BitUnsigned + Clone,
|
||||
{
|
||||
let q = q.max(1);
|
||||
|
||||
@@ -112,17 +116,14 @@ fn test_multiply_by_rational_saturating() {
|
||||
for value in 0..=div {
|
||||
for p in 0..=div {
|
||||
for q in 1..=div {
|
||||
let value: u64 = (value as u128 * u64::MAX as u128 / div as u128)
|
||||
.try_into().unwrap();
|
||||
let p = (p as u64 * u32::MAX as u64 / div as u64)
|
||||
.try_into().unwrap();
|
||||
let q = (q as u64 * u32::MAX as u64 / div as u64)
|
||||
.try_into().unwrap();
|
||||
let value: u64 =
|
||||
(value as u128 * u64::MAX as u128 / div as u128).try_into().unwrap();
|
||||
let p = (p as u64 * u32::MAX as u64 / div as u64).try_into().unwrap();
|
||||
let q = (q as u64 * u32::MAX as u64 / div as u64).try_into().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
multiply_by_rational_saturating(value, p, q),
|
||||
(value as u128 * p as u128 / q as u128)
|
||||
.try_into().unwrap_or(u64::MAX)
|
||||
(value as u128 * p as u128 / q as u128).try_into().unwrap_or(u64::MAX)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -153,10 +154,8 @@ fn test_calculate_for_fraction_times_denominator() {
|
||||
let div = 100u32;
|
||||
for d in 0..=div {
|
||||
for n in 0..=d {
|
||||
let d: u64 = (d as u128 * u64::MAX as u128 / div as u128)
|
||||
.try_into().unwrap();
|
||||
let n: u64 = (n as u128 * u64::MAX as u128 / div as u128)
|
||||
.try_into().unwrap();
|
||||
let d: u64 = (d as u128 * u64::MAX as u128 / div as u128).try_into().unwrap();
|
||||
let n: u64 = (n as u128 * u64::MAX as u128 / div as u128).try_into().unwrap();
|
||||
|
||||
let res = curve.calculate_for_fraction_times_denominator(n, d);
|
||||
let expected = formal_calculate_for_fraction_times_denominator(n, d);
|
||||
|
||||
@@ -23,14 +23,16 @@ use std::fmt;
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use sp_std::prelude::*;
|
||||
use sp_core::RuntimeDebug;
|
||||
use crate::codec::{Codec, Encode, Decode};
|
||||
use crate::traits::{
|
||||
self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize, MaybeMallocSizeOf,
|
||||
NumberFor,
|
||||
use crate::{
|
||||
codec::{Codec, Decode, Encode},
|
||||
traits::{
|
||||
self, Block as BlockT, Header as HeaderT, MaybeMallocSizeOf, MaybeSerialize, Member,
|
||||
NumberFor,
|
||||
},
|
||||
Justifications,
|
||||
};
|
||||
use crate::Justifications;
|
||||
use sp_core::RuntimeDebug;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
/// Something to identify a block.
|
||||
#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
|
||||
|
||||
@@ -18,11 +18,13 @@
|
||||
//! Generic implementation of an extrinsic that has passed the verification
|
||||
//! stage.
|
||||
|
||||
use crate::traits::{
|
||||
self, Member, MaybeDisplay, SignedExtension, Dispatchable, DispatchInfoOf, PostDispatchInfoOf,
|
||||
ValidateUnsigned,
|
||||
use crate::{
|
||||
traits::{
|
||||
self, DispatchInfoOf, Dispatchable, MaybeDisplay, Member, PostDispatchInfoOf,
|
||||
SignedExtension, ValidateUnsigned,
|
||||
},
|
||||
transaction_validity::{TransactionSource, TransactionValidity},
|
||||
};
|
||||
use crate::transaction_validity::{TransactionValidity, TransactionSource};
|
||||
|
||||
/// Definition of something that the external world might want to say; its
|
||||
/// existence implies that it has been checked and is good, particularly with
|
||||
@@ -37,12 +39,11 @@ pub struct CheckedExtrinsic<AccountId, Call, Extra> {
|
||||
pub function: Call,
|
||||
}
|
||||
|
||||
impl<AccountId, Call, Extra, Origin> traits::Applyable for
|
||||
CheckedExtrinsic<AccountId, Call, Extra>
|
||||
impl<AccountId, Call, Extra, Origin> traits::Applyable for CheckedExtrinsic<AccountId, Call, Extra>
|
||||
where
|
||||
AccountId: Member + MaybeDisplay,
|
||||
Call: Member + Dispatchable<Origin=Origin>,
|
||||
Extra: SignedExtension<AccountId=AccountId, Call=Call>,
|
||||
Call: Member + Dispatchable<Origin = Origin>,
|
||||
Extra: SignedExtension<AccountId = AccountId, Call = Call>,
|
||||
Origin: From<Option<AccountId>>,
|
||||
{
|
||||
type Call = Call;
|
||||
@@ -64,7 +65,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn apply<U: ValidateUnsigned<Call=Self::Call>>(
|
||||
fn apply<U: ValidateUnsigned<Call = Self::Call>>(
|
||||
self,
|
||||
info: &DispatchInfoOf<Self::Call>,
|
||||
len: usize,
|
||||
|
||||
@@ -22,8 +22,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use sp_std::prelude::*;
|
||||
|
||||
use crate::ConsensusEngineId;
|
||||
use crate::codec::{Decode, Encode, Input, Error};
|
||||
use crate::{
|
||||
codec::{Decode, Encode, Error, Input},
|
||||
ConsensusEngineId,
|
||||
};
|
||||
use sp_core::{ChangesTrieConfiguration, RuntimeDebug};
|
||||
|
||||
/// Generic header digest.
|
||||
@@ -40,7 +42,7 @@ pub struct Digest<Hash> {
|
||||
|
||||
impl<Item> Default for Digest<Item> {
|
||||
fn default() -> Self {
|
||||
Self { logs: Vec::new(), }
|
||||
Self { logs: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,12 +63,18 @@ impl<Hash> Digest<Hash> {
|
||||
}
|
||||
|
||||
/// Get reference to the first digest item that matches the passed predicate.
|
||||
pub fn log<T: ?Sized, F: Fn(&DigestItem<Hash>) -> Option<&T>>(&self, predicate: F) -> Option<&T> {
|
||||
pub fn log<T: ?Sized, F: Fn(&DigestItem<Hash>) -> Option<&T>>(
|
||||
&self,
|
||||
predicate: F,
|
||||
) -> Option<&T> {
|
||||
self.logs().iter().find_map(predicate)
|
||||
}
|
||||
|
||||
/// Get a conversion of the first digest item that successfully converts using the function.
|
||||
pub fn convert_first<T, F: Fn(&DigestItem<Hash>) -> Option<T>>(&self, predicate: F) -> Option<T> {
|
||||
pub fn convert_first<T, F: Fn(&DigestItem<Hash>) -> Option<T>>(
|
||||
&self,
|
||||
predicate: F,
|
||||
) -> Option<T> {
|
||||
self.logs().iter().find_map(predicate)
|
||||
}
|
||||
}
|
||||
@@ -132,16 +140,18 @@ pub enum ChangesTrieSignal {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<Hash: Encode> serde::Serialize for DigestItem<Hash> {
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
self.using_encoded(|bytes| {
|
||||
sp_core::bytes::serialize(bytes, seq)
|
||||
})
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.using_encoded(|bytes| sp_core::bytes::serialize(bytes, seq))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'a, Hash: Decode> serde::Deserialize<'a> for DigestItem<Hash> {
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error> where
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
let r = sp_core::bytes::deserialize(de)?;
|
||||
@@ -297,9 +307,7 @@ impl<Hash: Decode> Decode for DigestItem<Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
|
||||
let item_type: DigestItemType = Decode::decode(input)?;
|
||||
match item_type {
|
||||
DigestItemType::ChangesTrieRoot => Ok(Self::ChangesTrieRoot(
|
||||
Decode::decode(input)?,
|
||||
)),
|
||||
DigestItemType::ChangesTrieRoot => Ok(Self::ChangesTrieRoot(Decode::decode(input)?)),
|
||||
DigestItemType::PreRuntime => {
|
||||
let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
|
||||
Ok(Self::PreRuntime(vals.0, vals.1))
|
||||
@@ -307,17 +315,14 @@ impl<Hash: Decode> Decode for DigestItem<Hash> {
|
||||
DigestItemType::Consensus => {
|
||||
let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
|
||||
Ok(Self::Consensus(vals.0, vals.1))
|
||||
}
|
||||
},
|
||||
DigestItemType::Seal => {
|
||||
let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
|
||||
Ok(Self::Seal(vals.0, vals.1))
|
||||
},
|
||||
DigestItemType::ChangesTrieSignal => Ok(Self::ChangesTrieSignal(
|
||||
Decode::decode(input)?,
|
||||
)),
|
||||
DigestItemType::Other => Ok(Self::Other(
|
||||
Decode::decode(input)?,
|
||||
)),
|
||||
DigestItemType::ChangesTrieSignal =>
|
||||
Ok(Self::ChangesTrieSignal(Decode::decode(input)?)),
|
||||
DigestItemType::Other => Ok(Self::Other(Decode::decode(input)?)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,9 +381,10 @@ impl<'a, Hash> DigestItemRef<'a, Hash> {
|
||||
pub fn try_as_raw(&self, id: OpaqueDigestItemId) -> Option<&'a [u8]> {
|
||||
match (id, self) {
|
||||
(OpaqueDigestItemId::Consensus(w), &Self::Consensus(v, s)) |
|
||||
(OpaqueDigestItemId::Seal(w), &Self::Seal(v, s)) |
|
||||
(OpaqueDigestItemId::PreRuntime(w), &Self::PreRuntime(v, s))
|
||||
if v == w => Some(&s[..]),
|
||||
(OpaqueDigestItemId::Seal(w), &Self::Seal(v, s)) |
|
||||
(OpaqueDigestItemId::PreRuntime(w), &Self::PreRuntime(v, s))
|
||||
if v == w =>
|
||||
Some(&s[..]),
|
||||
(OpaqueDigestItemId::Other, &Self::Other(s)) => Some(&s[..]),
|
||||
_ => None,
|
||||
}
|
||||
@@ -395,8 +401,7 @@ impl<'a, Hash> DigestItemRef<'a, Hash> {
|
||||
/// Returns `None` if this isn't a seal item, the `id` doesn't match or when the decoding fails.
|
||||
pub fn seal_try_to<T: Decode>(&self, id: &ConsensusEngineId) -> Option<T> {
|
||||
match self {
|
||||
Self::Seal(v, s) if *v == id =>
|
||||
Decode::decode(&mut &s[..]).ok(),
|
||||
Self::Seal(v, s) if *v == id => Decode::decode(&mut &s[..]).ok(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -407,8 +412,7 @@ impl<'a, Hash> DigestItemRef<'a, Hash> {
|
||||
/// when the decoding fails.
|
||||
pub fn consensus_try_to<T: Decode>(&self, id: &ConsensusEngineId) -> Option<T> {
|
||||
match self {
|
||||
Self::Consensus(v, s) if *v == id =>
|
||||
Decode::decode(&mut &s[..]).ok(),
|
||||
Self::Consensus(v, s) if *v == id => Decode::decode(&mut &s[..]).ok(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -419,8 +423,7 @@ impl<'a, Hash> DigestItemRef<'a, Hash> {
|
||||
/// when the decoding fails.
|
||||
pub fn pre_runtime_try_to<T: Decode>(&self, id: &ConsensusEngineId) -> Option<T> {
|
||||
match self {
|
||||
Self::PreRuntime(v, s) if *v == id =>
|
||||
Decode::decode(&mut &s[..]).ok(),
|
||||
Self::PreRuntime(v, s) if *v == id => Decode::decode(&mut &s[..]).ok(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -482,7 +485,7 @@ mod tests {
|
||||
logs: vec![
|
||||
DigestItem::ChangesTrieRoot(4),
|
||||
DigestItem::Other(vec![1, 2, 3]),
|
||||
DigestItem::Seal(*b"test", vec![1, 2, 3])
|
||||
DigestItem::Seal(*b"test", vec![1, 2, 3]),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
//! Generic implementation of an unchecked (pre-verification) extrinsic.
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::codec::{Decode, Encode, Input, Output, Error};
|
||||
use crate::codec::{Decode, Encode, Error, Input, Output};
|
||||
|
||||
/// Era period
|
||||
pub type Period = u64;
|
||||
@@ -47,15 +47,13 @@ pub enum Era {
|
||||
Mortal(Period, Phase),
|
||||
}
|
||||
|
||||
/*
|
||||
* E.g. with period == 4:
|
||||
* 0 10 20 30 40
|
||||
* 0123456789012345678901234567890123456789012
|
||||
* |...|
|
||||
* authored -/ \- expiry
|
||||
* phase = 1
|
||||
* n = Q(current - phase, period) + phase
|
||||
*/
|
||||
// E.g. with period == 4:
|
||||
// 0 10 20 30 40
|
||||
// 0123456789012345678901234567890123456789012
|
||||
// |...|
|
||||
// authored -/ \- expiry
|
||||
// phase = 1
|
||||
// n = Q(current - phase, period) + phase
|
||||
impl Era {
|
||||
/// Create a new era based on a period (which should be a power of two between 4 and 65536 inclusive)
|
||||
/// and a block number on which it should start (or, for long periods, be shortly after the start).
|
||||
@@ -64,10 +62,7 @@ impl Era {
|
||||
/// does not exceed `BlockHashCount` parameter passed to `system` module, since that
|
||||
/// prunes old blocks and renders transactions immediately invalid.
|
||||
pub fn mortal(period: u64, current: u64) -> Self {
|
||||
let period = period.checked_next_power_of_two()
|
||||
.unwrap_or(1 << 16)
|
||||
.max(4)
|
||||
.min(1 << 16);
|
||||
let period = period.checked_next_power_of_two().unwrap_or(1 << 16).max(4).min(1 << 16);
|
||||
let phase = current % period;
|
||||
let quantize_factor = (period >> 12).max(1);
|
||||
let quantized_phase = phase / quantize_factor * quantize_factor;
|
||||
@@ -109,9 +104,10 @@ impl Encode for Era {
|
||||
Self::Immortal => output.push_byte(0),
|
||||
Self::Mortal(period, phase) => {
|
||||
let quantize_factor = (*period as u64 >> 12).max(1);
|
||||
let encoded = (period.trailing_zeros() - 1).max(1).min(15) as u16 | ((phase / quantize_factor) << 4) as u16;
|
||||
let encoded = (period.trailing_zeros() - 1).max(1).min(15) as u16 |
|
||||
((phase / quantize_factor) << 4) as u16;
|
||||
encoded.encode_to(output);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +149,7 @@ mod tests {
|
||||
assert!(e.is_immortal());
|
||||
|
||||
assert_eq!(e.encode(), vec![0u8]);
|
||||
assert_eq!(e, Era::decode(&mut&[0u8][..]).unwrap());
|
||||
assert_eq!(e, Era::decode(&mut &[0u8][..]).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -163,7 +159,7 @@ mod tests {
|
||||
|
||||
let expected = vec![5 + 42 % 16 * 16, 42 / 16];
|
||||
assert_eq!(e.encode(), expected);
|
||||
assert_eq!(e, Era::decode(&mut&expected[..]).unwrap());
|
||||
assert_eq!(e, Era::decode(&mut &expected[..]).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -172,7 +168,7 @@ mod tests {
|
||||
|
||||
let expected = vec![(14 + 2500 % 16 * 16) as u8, (2500 / 16) as u8];
|
||||
assert_eq!(e.encode(), expected);
|
||||
assert_eq!(e, Era::decode(&mut&expected[..]).unwrap());
|
||||
assert_eq!(e, Era::decode(&mut &expected[..]).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -17,20 +17,18 @@
|
||||
|
||||
//! Generic implementation of a block header.
|
||||
|
||||
use crate::{
|
||||
codec::{Codec, Decode, Encode, EncodeAsRef, Error, HasCompact, Input, Output},
|
||||
generic::Digest,
|
||||
traits::{
|
||||
self, AtLeast32BitUnsigned, Hash as HashT, MaybeDisplay, MaybeMallocSizeOf, MaybeSerialize,
|
||||
MaybeSerializeDeserialize, Member, SimpleBitOps,
|
||||
},
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error};
|
||||
use crate::traits::{
|
||||
self, Member, AtLeast32BitUnsigned, SimpleBitOps, Hash as HashT,
|
||||
MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay,
|
||||
MaybeMallocSizeOf,
|
||||
};
|
||||
use crate::generic::Digest;
|
||||
use sp_core::U256;
|
||||
use sp_std::{
|
||||
convert::TryFrom,
|
||||
fmt::Debug,
|
||||
};
|
||||
use sp_std::{convert::TryFrom, fmt::Debug};
|
||||
|
||||
/// Abstraction over a block header for a substrate chain.
|
||||
#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)]
|
||||
@@ -41,9 +39,10 @@ pub struct Header<Number: Copy + Into<U256> + TryFrom<U256>, Hash: HashT> {
|
||||
/// The parent hash.
|
||||
pub parent_hash: Hash::Output,
|
||||
/// The block number.
|
||||
#[cfg_attr(feature = "std", serde(
|
||||
serialize_with = "serialize_number",
|
||||
deserialize_with = "deserialize_number"))]
|
||||
#[cfg_attr(
|
||||
feature = "std",
|
||||
serde(serialize_with = "serialize_number", deserialize_with = "deserialize_number")
|
||||
)]
|
||||
pub number: Number,
|
||||
/// The state trie merkle root
|
||||
pub state_root: Hash::Output,
|
||||
@@ -71,21 +70,27 @@ where
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub fn serialize_number<S, T: Copy + Into<U256> + TryFrom<U256>>(
|
||||
val: &T, s: S,
|
||||
) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
val: &T,
|
||||
s: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let u256: U256 = (*val).into();
|
||||
serde::Serialize::serialize(&u256, s)
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub fn deserialize_number<'a, D, T: Copy + Into<U256> + TryFrom<U256>>(
|
||||
d: D,
|
||||
) -> Result<T, D::Error> where D: serde::Deserializer<'a> {
|
||||
pub fn deserialize_number<'a, D, T: Copy + Into<U256> + TryFrom<U256>>(d: D) -> Result<T, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
let u256: U256 = serde::Deserialize::deserialize(d)?;
|
||||
TryFrom::try_from(u256).map_err(|_| serde::de::Error::custom("Try from failed"))
|
||||
}
|
||||
|
||||
impl<Number, Hash> Decode for Header<Number, Hash> where
|
||||
impl<Number, Hash> Decode for Header<Number, Hash>
|
||||
where
|
||||
Number: HasCompact + Copy + Into<U256> + TryFrom<U256>,
|
||||
Hash: HashT,
|
||||
Hash::Output: Decode,
|
||||
@@ -101,51 +106,92 @@ impl<Number, Hash> Decode for Header<Number, Hash> where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Number, Hash> Encode for Header<Number, Hash> where
|
||||
impl<Number, Hash> Encode for Header<Number, Hash>
|
||||
where
|
||||
Number: HasCompact + Copy + Into<U256> + TryFrom<U256>,
|
||||
Hash: HashT,
|
||||
Hash::Output: Encode,
|
||||
{
|
||||
fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
|
||||
self.parent_hash.encode_to(dest);
|
||||
<<<Number as HasCompact>::Type as EncodeAsRef<_>>::RefType>::from(&self.number).encode_to(dest);
|
||||
<<<Number as HasCompact>::Type as EncodeAsRef<_>>::RefType>::from(&self.number)
|
||||
.encode_to(dest);
|
||||
self.state_root.encode_to(dest);
|
||||
self.extrinsics_root.encode_to(dest);
|
||||
self.digest.encode_to(dest);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Number, Hash> codec::EncodeLike for Header<Number, Hash> where
|
||||
impl<Number, Hash> codec::EncodeLike for Header<Number, Hash>
|
||||
where
|
||||
Number: HasCompact + Copy + Into<U256> + TryFrom<U256>,
|
||||
Hash: HashT,
|
||||
Hash::Output: Encode,
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
impl<Number, Hash> traits::Header for Header<Number, Hash> where
|
||||
Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + MaybeDisplay +
|
||||
AtLeast32BitUnsigned + Codec + Copy + Into<U256> + TryFrom<U256> + sp_std::str::FromStr +
|
||||
MaybeMallocSizeOf,
|
||||
impl<Number, Hash> traits::Header for Header<Number, Hash>
|
||||
where
|
||||
Number: Member
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug
|
||||
+ sp_std::hash::Hash
|
||||
+ MaybeDisplay
|
||||
+ AtLeast32BitUnsigned
|
||||
+ Codec
|
||||
+ Copy
|
||||
+ Into<U256>
|
||||
+ TryFrom<U256>
|
||||
+ sp_std::str::FromStr
|
||||
+ MaybeMallocSizeOf,
|
||||
Hash: HashT,
|
||||
Hash::Output: Default + sp_std::hash::Hash + Copy + Member + Ord +
|
||||
MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec + MaybeMallocSizeOf,
|
||||
Hash::Output: Default
|
||||
+ sp_std::hash::Hash
|
||||
+ Copy
|
||||
+ Member
|
||||
+ Ord
|
||||
+ MaybeSerialize
|
||||
+ Debug
|
||||
+ MaybeDisplay
|
||||
+ SimpleBitOps
|
||||
+ Codec
|
||||
+ MaybeMallocSizeOf,
|
||||
{
|
||||
type Number = Number;
|
||||
type Hash = <Hash as HashT>::Output;
|
||||
type Hashing = Hash;
|
||||
|
||||
fn number(&self) -> &Self::Number { &self.number }
|
||||
fn set_number(&mut self, num: Self::Number) { self.number = num }
|
||||
fn number(&self) -> &Self::Number {
|
||||
&self.number
|
||||
}
|
||||
fn set_number(&mut self, num: Self::Number) {
|
||||
self.number = num
|
||||
}
|
||||
|
||||
fn extrinsics_root(&self) -> &Self::Hash { &self.extrinsics_root }
|
||||
fn set_extrinsics_root(&mut self, root: Self::Hash) { self.extrinsics_root = root }
|
||||
fn extrinsics_root(&self) -> &Self::Hash {
|
||||
&self.extrinsics_root
|
||||
}
|
||||
fn set_extrinsics_root(&mut self, root: Self::Hash) {
|
||||
self.extrinsics_root = root
|
||||
}
|
||||
|
||||
fn state_root(&self) -> &Self::Hash { &self.state_root }
|
||||
fn set_state_root(&mut self, root: Self::Hash) { self.state_root = root }
|
||||
fn state_root(&self) -> &Self::Hash {
|
||||
&self.state_root
|
||||
}
|
||||
fn set_state_root(&mut self, root: Self::Hash) {
|
||||
self.state_root = root
|
||||
}
|
||||
|
||||
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
|
||||
fn set_parent_hash(&mut self, hash: Self::Hash) { self.parent_hash = hash }
|
||||
fn parent_hash(&self) -> &Self::Hash {
|
||||
&self.parent_hash
|
||||
}
|
||||
fn set_parent_hash(&mut self, hash: Self::Hash) {
|
||||
self.parent_hash = hash
|
||||
}
|
||||
|
||||
fn digest(&self) -> &Digest<Self::Hash> { &self.digest }
|
||||
fn digest(&self) -> &Digest<Self::Hash> {
|
||||
&self.digest
|
||||
}
|
||||
|
||||
fn digest_mut(&mut self) -> &mut Digest<Self::Hash> {
|
||||
#[cfg(feature = "std")]
|
||||
@@ -160,22 +206,24 @@ impl<Number, Hash> traits::Header for Header<Number, Hash> where
|
||||
parent_hash: Self::Hash,
|
||||
digest: Digest<Self::Hash>,
|
||||
) -> Self {
|
||||
Self {
|
||||
number,
|
||||
extrinsics_root,
|
||||
state_root,
|
||||
parent_hash,
|
||||
digest,
|
||||
}
|
||||
Self { number, extrinsics_root, state_root, parent_hash, digest }
|
||||
}
|
||||
}
|
||||
|
||||
impl<Number, Hash> Header<Number, Hash> where
|
||||
Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32BitUnsigned + Codec +
|
||||
Into<U256> + TryFrom<U256>,
|
||||
impl<Number, Hash> Header<Number, Hash>
|
||||
where
|
||||
Number: Member
|
||||
+ sp_std::hash::Hash
|
||||
+ Copy
|
||||
+ MaybeDisplay
|
||||
+ AtLeast32BitUnsigned
|
||||
+ Codec
|
||||
+ Into<U256>
|
||||
+ TryFrom<U256>,
|
||||
Hash: HashT,
|
||||
Hash::Output: Default + sp_std::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
|
||||
{
|
||||
Hash::Output:
|
||||
Default + sp_std::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
|
||||
{
|
||||
/// Convenience helper for computing the hash of the header without having
|
||||
/// to import the trait.
|
||||
pub fn hash(&self) -> Hash::Output {
|
||||
|
||||
@@ -19,22 +19,22 @@
|
||||
//! Generic implementations of Extrinsic/Header/Block.
|
||||
// end::description[]
|
||||
|
||||
mod unchecked_extrinsic;
|
||||
mod era;
|
||||
mod checked_extrinsic;
|
||||
mod header;
|
||||
mod block;
|
||||
mod checked_extrinsic;
|
||||
mod digest;
|
||||
mod era;
|
||||
mod header;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod unchecked_extrinsic;
|
||||
|
||||
pub use self::unchecked_extrinsic::{UncheckedExtrinsic, SignedPayload};
|
||||
pub use self::era::{Era, Phase};
|
||||
pub use self::checked_extrinsic::CheckedExtrinsic;
|
||||
pub use self::header::Header;
|
||||
pub use self::block::{Block, SignedBlock, BlockId};
|
||||
pub use self::digest::{
|
||||
Digest, DigestItem, DigestItemRef, OpaqueDigestItemId, ChangesTrieSignal,
|
||||
pub use self::{
|
||||
block::{Block, BlockId, SignedBlock},
|
||||
checked_extrinsic::CheckedExtrinsic,
|
||||
digest::{ChangesTrieSignal, Digest, DigestItem, DigestItemRef, OpaqueDigestItemId},
|
||||
era::{Era, Phase},
|
||||
header::Header,
|
||||
unchecked_extrinsic::{SignedPayload, UncheckedExtrinsic},
|
||||
};
|
||||
|
||||
use crate::codec::Encode;
|
||||
|
||||
@@ -17,27 +17,23 @@
|
||||
|
||||
//! Tests for the generic implementations of Extrinsic/Header/Block.
|
||||
|
||||
use super::DigestItem;
|
||||
use crate::codec::{Decode, Encode};
|
||||
use sp_core::H256;
|
||||
use super::DigestItem;
|
||||
|
||||
#[test]
|
||||
fn system_digest_item_encoding() {
|
||||
let item = DigestItem::ChangesTrieRoot::<H256>(H256::default());
|
||||
let encoded = item.encode();
|
||||
assert_eq!(encoded, vec![
|
||||
// type = DigestItemType::ChangesTrieRoot
|
||||
2,
|
||||
// trie root
|
||||
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, 0,
|
||||
]);
|
||||
assert_eq!(
|
||||
encoded,
|
||||
vec![
|
||||
// type = DigestItemType::ChangesTrieRoot
|
||||
2, // trie root
|
||||
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, 0,
|
||||
]
|
||||
);
|
||||
|
||||
let decoded: DigestItem<H256> = Decode::decode(&mut &encoded[..]).unwrap();
|
||||
assert_eq!(item, decoded);
|
||||
@@ -47,14 +43,15 @@ fn system_digest_item_encoding() {
|
||||
fn non_system_digest_item_encoding() {
|
||||
let item = DigestItem::Other::<H256>(vec![10, 20, 30]);
|
||||
let encoded = item.encode();
|
||||
assert_eq!(encoded, vec![
|
||||
// type = DigestItemType::Other
|
||||
0,
|
||||
// length of other data
|
||||
12,
|
||||
// authorities
|
||||
10, 20, 30,
|
||||
]);
|
||||
assert_eq!(
|
||||
encoded,
|
||||
vec![
|
||||
// type = DigestItemType::Other
|
||||
0, // length of other data
|
||||
12, // authorities
|
||||
10, 20, 30,
|
||||
]
|
||||
);
|
||||
|
||||
let decoded: DigestItem<H256> = Decode::decode(&mut &encoded[..]).unwrap();
|
||||
assert_eq!(item, decoded);
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
|
||||
//! Generic implementation of an unchecked (pre-verification) extrinsic.
|
||||
|
||||
use sp_std::{fmt, prelude::*};
|
||||
use sp_io::hashing::blake2_256;
|
||||
use codec::{Decode, Encode, EncodeLike, Input, Error};
|
||||
use crate::{
|
||||
traits::{
|
||||
self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic, ExtrinsicMetadata,
|
||||
IdentifyAccount,
|
||||
},
|
||||
generic::CheckedExtrinsic,
|
||||
transaction_validity::{TransactionValidityError, InvalidTransaction},
|
||||
traits::{
|
||||
self, Checkable, Extrinsic, ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member,
|
||||
SignedExtension,
|
||||
},
|
||||
transaction_validity::{InvalidTransaction, TransactionValidityError},
|
||||
OpaqueExtrinsic,
|
||||
};
|
||||
use codec::{Decode, Encode, EncodeLike, Error, Input};
|
||||
use sp_io::hashing::blake2_256;
|
||||
use sp_std::{fmt, prelude::*};
|
||||
|
||||
/// Current version of the [`UncheckedExtrinsic`] format.
|
||||
const EXTRINSIC_VERSION: u8 = 4;
|
||||
@@ -38,7 +38,7 @@ const EXTRINSIC_VERSION: u8 = 4;
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
where
|
||||
Extra: SignedExtension
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
/// The signature, address, number of extrinsics have come before from
|
||||
/// the same signer and an era describing the longevity of this transaction,
|
||||
@@ -52,7 +52,7 @@ where
|
||||
impl<Address, Call, Signature, Extra> parity_util_mem::MallocSizeOf
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
where
|
||||
Extra: SignedExtension
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
fn size_of(&self, _ops: &mut parity_util_mem::MallocSizeOfOps) -> usize {
|
||||
// Instantiated only in runtime.
|
||||
@@ -64,24 +64,13 @@ impl<Address, Call, Signature, Extra: SignedExtension>
|
||||
UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
{
|
||||
/// New instance of a signed extrinsic aka "transaction".
|
||||
pub fn new_signed(
|
||||
function: Call,
|
||||
signed: Address,
|
||||
signature: Signature,
|
||||
extra: Extra
|
||||
) -> Self {
|
||||
Self {
|
||||
signature: Some((signed, signature, extra)),
|
||||
function,
|
||||
}
|
||||
pub fn new_signed(function: Call, signed: Address, signature: Signature, extra: Extra) -> Self {
|
||||
Self { signature: Some((signed, signature, extra)), function }
|
||||
}
|
||||
|
||||
/// New instance of an unsigned extrinsic aka "inherent".
|
||||
pub fn new_unsigned(function: Call) -> Self {
|
||||
Self {
|
||||
signature: None,
|
||||
function,
|
||||
}
|
||||
Self { signature: None, function }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,11 +79,7 @@ impl<Address, Call, Signature, Extra: SignedExtension> Extrinsic
|
||||
{
|
||||
type Call = Call;
|
||||
|
||||
type SignaturePayload = (
|
||||
Address,
|
||||
Signature,
|
||||
Extra,
|
||||
);
|
||||
type SignaturePayload = (Address, Signature, Extra);
|
||||
|
||||
fn is_signed(&self) -> Option<bool> {
|
||||
Some(self.signature.is_some())
|
||||
@@ -109,18 +94,16 @@ impl<Address, Call, Signature, Extra: SignedExtension> Extrinsic
|
||||
}
|
||||
}
|
||||
|
||||
impl<Address, AccountId, Call, Signature, Extra, Lookup>
|
||||
Checkable<Lookup>
|
||||
for
|
||||
UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
impl<Address, AccountId, Call, Signature, Extra, Lookup> Checkable<Lookup>
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
where
|
||||
Address: Member + MaybeDisplay,
|
||||
Call: Encode + Member,
|
||||
Signature: Member + traits::Verify,
|
||||
<Signature as traits::Verify>::Signer: IdentifyAccount<AccountId=AccountId>,
|
||||
Extra: SignedExtension<AccountId=AccountId>,
|
||||
<Signature as traits::Verify>::Signer: IdentifyAccount<AccountId = AccountId>,
|
||||
Extra: SignedExtension<AccountId = AccountId>,
|
||||
AccountId: Member + MaybeDisplay,
|
||||
Lookup: traits::Lookup<Source=Address, Target=AccountId>,
|
||||
Lookup: traits::Lookup<Source = Address, Target = AccountId>,
|
||||
{
|
||||
type Checked = CheckedExtrinsic<AccountId, Call, Extra>;
|
||||
|
||||
@@ -134,23 +117,17 @@ where
|
||||
}
|
||||
|
||||
let (function, extra, _) = raw_payload.deconstruct();
|
||||
CheckedExtrinsic {
|
||||
signed: Some((signed, extra)),
|
||||
function,
|
||||
}
|
||||
}
|
||||
None => CheckedExtrinsic {
|
||||
signed: None,
|
||||
function: self.function,
|
||||
CheckedExtrinsic { signed: Some((signed, extra)), function }
|
||||
},
|
||||
None => CheckedExtrinsic { signed: None, function: self.function },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Address, Call, Signature, Extra> ExtrinsicMetadata
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
where
|
||||
Extra: SignedExtension,
|
||||
where
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
const VERSION: u8 = EXTRINSIC_VERSION;
|
||||
type SignedExtensions = Extra;
|
||||
@@ -161,13 +138,10 @@ impl<Address, Call, Signature, Extra> ExtrinsicMetadata
|
||||
/// Note that the payload that we sign to produce unchecked extrinsic signature
|
||||
/// is going to be different than the `SignaturePayload` - so the thing the extrinsic
|
||||
/// actually contains.
|
||||
pub struct SignedPayload<Call, Extra: SignedExtension>((
|
||||
Call,
|
||||
Extra,
|
||||
Extra::AdditionalSigned,
|
||||
));
|
||||
pub struct SignedPayload<Call, Extra: SignedExtension>((Call, Extra, Extra::AdditionalSigned));
|
||||
|
||||
impl<Call, Extra> SignedPayload<Call, Extra> where
|
||||
impl<Call, Extra> SignedPayload<Call, Extra>
|
||||
where
|
||||
Call: Encode,
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
@@ -191,7 +165,8 @@ impl<Call, Extra> SignedPayload<Call, Extra> where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call, Extra> Encode for SignedPayload<Call, Extra> where
|
||||
impl<Call, Extra> Encode for SignedPayload<Call, Extra>
|
||||
where
|
||||
Call: Encode,
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
@@ -213,10 +188,10 @@ impl<Call, Extra> EncodeLike for SignedPayload<Call, Extra>
|
||||
where
|
||||
Call: Encode,
|
||||
Extra: SignedExtension,
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
impl<Address, Call, Signature, Extra> Decode
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
impl<Address, Call, Signature, Extra> Decode for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
where
|
||||
Address: Decode,
|
||||
Signature: Decode,
|
||||
@@ -235,7 +210,7 @@ where
|
||||
let is_signed = version & 0b1000_0000 != 0;
|
||||
let version = version & 0b0111_1111;
|
||||
if version != EXTRINSIC_VERSION {
|
||||
return Err("Invalid transaction version".into());
|
||||
return Err("Invalid transaction version".into())
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
@@ -245,8 +220,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Address, Call, Signature, Extra> Encode
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
impl<Address, Call, Signature, Extra> Encode for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
where
|
||||
Address: Encode,
|
||||
Signature: Encode,
|
||||
@@ -260,10 +234,10 @@ where
|
||||
Some(s) => {
|
||||
v.push(EXTRINSIC_VERSION | 0b1000_0000);
|
||||
s.encode_to(v);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
v.push(EXTRINSIC_VERSION & 0b0111_1111);
|
||||
}
|
||||
},
|
||||
}
|
||||
self.function.encode_to(v);
|
||||
})
|
||||
@@ -277,22 +251,27 @@ where
|
||||
Signature: Encode,
|
||||
Call: Encode,
|
||||
Extra: SignedExtension,
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<Address: Encode, Signature: Encode, Call: Encode, Extra: SignedExtension> serde::Serialize
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
{
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: ::serde::Serializer,
|
||||
{
|
||||
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extra: SignedExtension> serde::Deserialize<'a>
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extra: SignedExtension>
|
||||
serde::Deserialize<'a> for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
{
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error> where
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
let r = sp_core::bytes::deserialize(de)?;
|
||||
@@ -327,21 +306,22 @@ where
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
fn from(extrinsic: UncheckedExtrinsic<Address, Call, Signature, Extra>) -> Self {
|
||||
Self::from_bytes(extrinsic.encode().as_slice())
|
||||
.expect(
|
||||
"both OpaqueExtrinsic and UncheckedExtrinsic have encoding that is compatible with \
|
||||
raw Vec<u8> encoding; qed"
|
||||
)
|
||||
Self::from_bytes(extrinsic.encode().as_slice()).expect(
|
||||
"both OpaqueExtrinsic and UncheckedExtrinsic have encoding that is compatible with \
|
||||
raw Vec<u8> encoding; qed",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
codec::{Decode, Encode},
|
||||
testing::TestSignature as TestSig,
|
||||
traits::{IdentityLookup, SignedExtension},
|
||||
};
|
||||
use sp_io::hashing::blake2_256;
|
||||
use crate::codec::{Encode, Decode};
|
||||
use crate::traits::{SignedExtension, IdentityLookup};
|
||||
use crate::testing::TestSignature as TestSig;
|
||||
|
||||
type TestContext = IdentityLookup<u64>;
|
||||
type TestAccountId = u64;
|
||||
@@ -359,7 +339,9 @@ mod tests {
|
||||
type AdditionalSigned = ();
|
||||
type Pre = ();
|
||||
|
||||
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
|
||||
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
type Ex = UncheckedExtrinsic<TestAccountId, TestCall, TestSig, TestExtra>;
|
||||
@@ -378,7 +360,7 @@ mod tests {
|
||||
vec![0u8; 0],
|
||||
TEST_ACCOUNT,
|
||||
TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()),
|
||||
TestExtra
|
||||
TestExtra,
|
||||
);
|
||||
let encoded = ux.encode();
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
|
||||
@@ -389,9 +371,11 @@ mod tests {
|
||||
let ux = Ex::new_signed(
|
||||
vec![0u8; 0],
|
||||
TEST_ACCOUNT,
|
||||
TestSig(TEST_ACCOUNT, (vec![0u8; 257], TestExtra)
|
||||
.using_encoded(blake2_256)[..].to_owned()),
|
||||
TestExtra
|
||||
TestSig(
|
||||
TEST_ACCOUNT,
|
||||
(vec![0u8; 257], TestExtra).using_encoded(blake2_256)[..].to_owned(),
|
||||
),
|
||||
TestExtra,
|
||||
);
|
||||
let encoded = ux.encode();
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
// to allow benchmarking
|
||||
#![cfg_attr(feature = "bench", feature(test))]
|
||||
#[cfg(feature = "bench")] extern crate test;
|
||||
#[cfg(feature = "bench")]
|
||||
extern crate test;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use codec;
|
||||
@@ -41,22 +41,26 @@ pub use sp_application_crypto as app_crypto;
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_core::storage::{Storage, StorageChild};
|
||||
|
||||
use sp_std::prelude::*;
|
||||
use sp_std::convert::TryFrom;
|
||||
use sp_core::{crypto::{self, Public}, ed25519, sr25519, ecdsa, hash::{H256, H512}};
|
||||
use sp_core::{
|
||||
crypto::{self, Public},
|
||||
ecdsa, ed25519,
|
||||
hash::{H256, H512},
|
||||
sr25519,
|
||||
};
|
||||
use sp_std::{convert::TryFrom, prelude::*};
|
||||
|
||||
use codec::{Encode, Decode};
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
pub mod curve;
|
||||
pub mod generic;
|
||||
mod multiaddress;
|
||||
pub mod offchain;
|
||||
pub mod runtime_logger;
|
||||
mod runtime_string;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod testing;
|
||||
pub mod traits;
|
||||
pub mod transaction_validity;
|
||||
mod runtime_string;
|
||||
mod multiaddress;
|
||||
pub mod runtime_logger;
|
||||
|
||||
pub use crate::runtime_string::*;
|
||||
|
||||
@@ -64,25 +68,28 @@ pub use crate::runtime_string::*;
|
||||
pub use multiaddress::MultiAddress;
|
||||
|
||||
/// Re-export these since they're only "kind of" generic.
|
||||
pub use generic::{DigestItem, Digest};
|
||||
pub use generic::{Digest, DigestItem};
|
||||
|
||||
pub use sp_application_crypto::{BoundToRuntimeAppPublic, RuntimeAppPublic};
|
||||
/// Re-export this since it's part of the API of this crate.
|
||||
pub use sp_core::{TypeId, crypto::{key_types, KeyTypeId, CryptoType, CryptoTypeId, AccountId32}};
|
||||
pub use sp_application_crypto::{RuntimeAppPublic, BoundToRuntimeAppPublic};
|
||||
pub use sp_core::{
|
||||
crypto::{key_types, AccountId32, CryptoType, CryptoTypeId, KeyTypeId},
|
||||
TypeId,
|
||||
};
|
||||
|
||||
/// Re-export `RuntimeDebug`, to avoid dependency clutter.
|
||||
pub use sp_core::RuntimeDebug;
|
||||
|
||||
/// Re-export top-level arithmetic stuff.
|
||||
pub use sp_arithmetic::{
|
||||
PerThing, Perquintill, Perbill, Permill, Percent, PerU16, InnerOf, UpperOf,
|
||||
Rational128, FixedI64, FixedI128, FixedU128, FixedPointNumber, FixedPointOperand,
|
||||
traits::SaturatedConversion,
|
||||
};
|
||||
/// Re-export 128 bit helpers.
|
||||
pub use sp_arithmetic::helpers_128bit;
|
||||
/// Re-export big_uint stuff.
|
||||
pub use sp_arithmetic::biguint;
|
||||
/// Re-export 128 bit helpers.
|
||||
pub use sp_arithmetic::helpers_128bit;
|
||||
/// Re-export top-level arithmetic stuff.
|
||||
pub use sp_arithmetic::{
|
||||
traits::SaturatedConversion, FixedI128, FixedI64, FixedPointNumber, FixedPointOperand,
|
||||
FixedU128, InnerOf, PerThing, PerU16, Perbill, Percent, Permill, Perquintill, Rational128,
|
||||
UpperOf,
|
||||
};
|
||||
|
||||
pub use either::Either;
|
||||
|
||||
@@ -119,7 +126,7 @@ impl Justifications {
|
||||
/// not inserted.
|
||||
pub fn append(&mut self, justification: Justification) -> bool {
|
||||
if self.get(justification.0).is_some() {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
self.0.push(justification);
|
||||
true
|
||||
@@ -153,11 +160,11 @@ impl From<Justification> for Justifications {
|
||||
}
|
||||
}
|
||||
|
||||
use traits::{Verify, Lazy};
|
||||
use traits::{Lazy, Verify};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use serde::{Serialize, Deserialize, de::DeserializeOwned};
|
||||
use crate::traits::IdentifyAccount;
|
||||
#[cfg(feature = "std")]
|
||||
pub use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
|
||||
/// Complex storage builder stuff.
|
||||
#[cfg(feature = "std")]
|
||||
@@ -169,10 +176,7 @@ pub trait BuildStorage {
|
||||
Ok(storage)
|
||||
}
|
||||
/// Assimilate the storage for this module into pre-existing overlays.
|
||||
fn assimilate_storage(
|
||||
&self,
|
||||
storage: &mut sp_core::storage::Storage,
|
||||
) -> Result<(), String>;
|
||||
fn assimilate_storage(&self, storage: &mut sp_core::storage::Storage) -> Result<(), String>;
|
||||
}
|
||||
|
||||
/// Something that can build the genesis storage of a module.
|
||||
@@ -187,17 +191,14 @@ pub trait BuildModuleGenesisStorage<T, I>: Sized {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl BuildStorage for sp_core::storage::Storage {
|
||||
fn assimilate_storage(
|
||||
&self,
|
||||
storage: &mut sp_core::storage::Storage,
|
||||
)-> Result<(), String> {
|
||||
fn assimilate_storage(&self, storage: &mut sp_core::storage::Storage) -> Result<(), String> {
|
||||
storage.top.extend(self.top.iter().map(|(k, v)| (k.clone(), v.clone())));
|
||||
for (k, other_map) in self.children_default.iter() {
|
||||
let k = k.clone();
|
||||
if let Some(map) = storage.children_default.get_mut(&k) {
|
||||
map.data.extend(other_map.data.iter().map(|(k, v)| (k.clone(), v.clone())));
|
||||
if !map.child_info.try_update(&other_map.child_info) {
|
||||
return Err("Incompatible child info update".to_string());
|
||||
return Err("Incompatible child info update".to_string())
|
||||
}
|
||||
} else {
|
||||
storage.children_default.insert(k, other_map.clone());
|
||||
@@ -209,10 +210,7 @@ impl BuildStorage for sp_core::storage::Storage {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl BuildStorage for () {
|
||||
fn assimilate_storage(
|
||||
&self,
|
||||
_: &mut sp_core::storage::Storage,
|
||||
) -> Result<(), String> {
|
||||
fn assimilate_storage(&self, _: &mut sp_core::storage::Storage) -> Result<(), String> {
|
||||
Err("`assimilate_storage` not implemented for `()`".into())
|
||||
}
|
||||
}
|
||||
@@ -241,7 +239,11 @@ impl From<ed25519::Signature> for MultiSignature {
|
||||
impl TryFrom<MultiSignature> for ed25519::Signature {
|
||||
type Error = ();
|
||||
fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
|
||||
if let MultiSignature::Ed25519(x) = m { Ok(x) } else { Err(()) }
|
||||
if let MultiSignature::Ed25519(x) = m {
|
||||
Ok(x)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +256,11 @@ impl From<sr25519::Signature> for MultiSignature {
|
||||
impl TryFrom<MultiSignature> for sr25519::Signature {
|
||||
type Error = ();
|
||||
fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
|
||||
if let MultiSignature::Sr25519(x) = m { Ok(x) } else { Err(()) }
|
||||
if let MultiSignature::Sr25519(x) = m {
|
||||
Ok(x)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +273,11 @@ impl From<ecdsa::Signature> for MultiSignature {
|
||||
impl TryFrom<MultiSignature> for ecdsa::Signature {
|
||||
type Error = ();
|
||||
fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
|
||||
if let MultiSignature::Ecdsa(x) = m { Ok(x) } else { Err(()) }
|
||||
if let MultiSignature::Ecdsa(x) = m {
|
||||
Ok(x)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +343,11 @@ impl From<ed25519::Public> for MultiSigner {
|
||||
impl TryFrom<MultiSigner> for ed25519::Public {
|
||||
type Error = ();
|
||||
fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
|
||||
if let MultiSigner::Ed25519(x) = m { Ok(x) } else { Err(()) }
|
||||
if let MultiSigner::Ed25519(x) = m {
|
||||
Ok(x)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +360,11 @@ impl From<sr25519::Public> for MultiSigner {
|
||||
impl TryFrom<MultiSigner> for sr25519::Public {
|
||||
type Error = ();
|
||||
fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
|
||||
if let MultiSigner::Sr25519(x) = m { Ok(x) } else { Err(()) }
|
||||
if let MultiSigner::Sr25519(x) = m {
|
||||
Ok(x)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +377,11 @@ impl From<ecdsa::Public> for MultiSigner {
|
||||
impl TryFrom<MultiSigner> for ecdsa::Public {
|
||||
type Error = ();
|
||||
fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
|
||||
if let MultiSigner::Ecdsa(x) = m { Ok(x) } else { Err(()) }
|
||||
if let MultiSigner::Ecdsa(x) = m {
|
||||
Ok(x)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,17 +400,19 @@ impl Verify for MultiSignature {
|
||||
type Signer = MultiSigner;
|
||||
fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &AccountId32) -> bool {
|
||||
match (self, signer) {
|
||||
(Self::Ed25519(ref sig), who) => sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())),
|
||||
(Self::Sr25519(ref sig), who) => sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())),
|
||||
(Self::Ed25519(ref sig), who) =>
|
||||
sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())),
|
||||
(Self::Sr25519(ref sig), who) =>
|
||||
sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())),
|
||||
(Self::Ecdsa(ref sig), who) => {
|
||||
let m = sp_io::hashing::blake2_256(msg.get());
|
||||
match sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) {
|
||||
Ok(pubkey) =>
|
||||
&sp_io::hashing::blake2_256(pubkey.as_ref())
|
||||
== <dyn AsRef<[u8; 32]>>::as_ref(who),
|
||||
&sp_io::hashing::blake2_256(pubkey.as_ref()) ==
|
||||
<dyn AsRef<[u8; 32]>>::as_ref(who),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,10 +428,10 @@ impl Verify for AnySignature {
|
||||
let msg = msg.get();
|
||||
sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
|
||||
.map(|s| s.verify(msg, signer))
|
||||
.unwrap_or(false)
|
||||
|| ed25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
|
||||
.map(|s| s.verify(msg, &ed25519::Public::from_slice(signer.as_ref())))
|
||||
.unwrap_or(false)
|
||||
.unwrap_or(false) ||
|
||||
ed25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
|
||||
.map(|s| s.verify(msg, &ed25519::Public::from_slice(signer.as_ref())))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,7 +467,11 @@ pub type DispatchResultWithInfo<T> = sp_std::result::Result<T, DispatchErrorWith
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub enum DispatchError {
|
||||
/// Some error occurred.
|
||||
Other(#[codec(skip)] #[cfg_attr(feature = "std", serde(skip_deserializing))] &'static str),
|
||||
Other(
|
||||
#[codec(skip)]
|
||||
#[cfg_attr(feature = "std", serde(skip_deserializing))]
|
||||
&'static str,
|
||||
),
|
||||
/// Failed to lookup some data.
|
||||
CannotLookup,
|
||||
/// A bad origin.
|
||||
@@ -472,8 +500,9 @@ pub enum DispatchError {
|
||||
/// Result of a `Dispatchable` which contains the `DispatchResult` and additional information about
|
||||
/// the `Dispatchable` that is only known post dispatch.
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)]
|
||||
pub struct DispatchErrorWithPostInfo<Info> where
|
||||
Info: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable
|
||||
pub struct DispatchErrorWithPostInfo<Info>
|
||||
where
|
||||
Info: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable,
|
||||
{
|
||||
/// Additional information about the `Dispatchable` which is only known post dispatch.
|
||||
pub post_info: Info,
|
||||
@@ -485,22 +514,20 @@ impl DispatchError {
|
||||
/// Return the same error but without the attached message.
|
||||
pub fn stripped(self) -> Self {
|
||||
match self {
|
||||
DispatchError::Module { index, error, message: Some(_) }
|
||||
=> DispatchError::Module { index, error, message: None },
|
||||
DispatchError::Module { index, error, message: Some(_) } =>
|
||||
DispatchError::Module { index, error, message: None },
|
||||
m => m,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> From<E> for DispatchErrorWithPostInfo<T> where
|
||||
impl<T, E> From<E> for DispatchErrorWithPostInfo<T>
|
||||
where
|
||||
T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable + Default,
|
||||
E: Into<DispatchError>
|
||||
E: Into<DispatchError>,
|
||||
{
|
||||
fn from(error: E) -> Self {
|
||||
Self {
|
||||
post_info: Default::default(),
|
||||
error: error.into(),
|
||||
}
|
||||
Self { post_info: Default::default(), error: error.into() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,8 +632,9 @@ impl From<DispatchError> for &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<DispatchErrorWithPostInfo<T>> for &'static str where
|
||||
T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable
|
||||
impl<T> From<DispatchErrorWithPostInfo<T>> for &'static str
|
||||
where
|
||||
T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable,
|
||||
{
|
||||
fn from(err: DispatchErrorWithPostInfo<T>) -> &'static str {
|
||||
err.error.into()
|
||||
@@ -626,7 +654,7 @@ impl traits::Printable for DispatchError {
|
||||
if let Some(msg) = message {
|
||||
msg.print();
|
||||
}
|
||||
}
|
||||
},
|
||||
Self::ConsumerRemaining => "Consumer remaining".print(),
|
||||
Self::NoProviders => "No providers".print(),
|
||||
Self::Token(e) => {
|
||||
@@ -636,13 +664,14 @@ impl traits::Printable for DispatchError {
|
||||
Self::Arithmetic(e) => {
|
||||
"Arithmetic error: ".print();
|
||||
<&'static str>::from(*e).print();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> traits::Printable for DispatchErrorWithPostInfo<T> where
|
||||
T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable
|
||||
impl<T> traits::Printable for DispatchErrorWithPostInfo<T>
|
||||
where
|
||||
T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable,
|
||||
{
|
||||
fn print(&self) {
|
||||
self.error.print();
|
||||
@@ -704,7 +733,8 @@ pub type DispatchOutcome = Result<(), DispatchError>;
|
||||
/// - The sender doesn't have enough funds to pay the transaction inclusion fee. Including such
|
||||
/// a transaction in the block doesn't make sense.
|
||||
/// - The extrinsic supplied a bad signature. This transaction won't become valid ever.
|
||||
pub type ApplyExtrinsicResult = Result<DispatchOutcome, transaction_validity::TransactionValidityError>;
|
||||
pub type ApplyExtrinsicResult =
|
||||
Result<DispatchOutcome, transaction_validity::TransactionValidityError>;
|
||||
|
||||
/// Same as `ApplyExtrinsicResult` but augmented with `PostDispatchInfo` on success.
|
||||
pub type ApplyExtrinsicResultWithInfo<T> =
|
||||
@@ -715,7 +745,7 @@ pub type ApplyExtrinsicResultWithInfo<T> =
|
||||
pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>(
|
||||
sig: &V,
|
||||
item: &T,
|
||||
signer: &<V::Signer as IdentifyAccount>::AccountId
|
||||
signer: &<V::Signer as IdentifyAccount>::AccountId,
|
||||
) -> bool {
|
||||
// The `Lazy<T>` trait expresses something like `X: FnMut<Output = for<'a> &'a T>`.
|
||||
// unfortunately this is a lifetime relationship that can't
|
||||
@@ -732,10 +762,7 @@ pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>(
|
||||
}
|
||||
}
|
||||
|
||||
sig.verify(
|
||||
LazyEncode { inner: || item.encode(), encoded: None },
|
||||
signer,
|
||||
)
|
||||
sig.verify(LazyEncode { inner: || item.encode(), encoded: None }, signer)
|
||||
}
|
||||
|
||||
/// Checks that `$x` is equal to `$y` with an error rate of `$error`.
|
||||
@@ -802,14 +829,20 @@ impl sp_std::fmt::Debug for OpaqueExtrinsic {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl ::serde::Serialize for OpaqueExtrinsic {
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: ::serde::Serializer,
|
||||
{
|
||||
codec::Encode::using_encoded(&self.0, |bytes| ::sp_core::bytes::serialize(bytes, seq))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic {
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error> where D: ::serde::Deserializer<'a> {
|
||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: ::serde::Deserializer<'a>,
|
||||
{
|
||||
let r = ::sp_core::bytes::deserialize(de)?;
|
||||
Decode::decode(&mut &r[..])
|
||||
.map_err(|e| ::serde::de::Error::custom(format!("Decode error: {}", e)))
|
||||
@@ -881,7 +914,7 @@ impl<R> TransactionOutcome<R> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codec::{Encode, Decode};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_core::crypto::Pair;
|
||||
|
||||
#[test]
|
||||
@@ -892,22 +925,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn dispatch_error_encoding() {
|
||||
let error = DispatchError::Module {
|
||||
index: 1,
|
||||
error: 2,
|
||||
message: Some("error message"),
|
||||
};
|
||||
let error = DispatchError::Module { index: 1, error: 2, message: Some("error message") };
|
||||
let encoded = error.encode();
|
||||
let decoded = DispatchError::decode(&mut &encoded[..]).unwrap();
|
||||
assert_eq!(encoded, vec![3, 1, 2]);
|
||||
assert_eq!(
|
||||
decoded,
|
||||
DispatchError::Module {
|
||||
index: 1,
|
||||
error: 2,
|
||||
message: None,
|
||||
},
|
||||
);
|
||||
assert_eq!(decoded, DispatchError::Module { index: 1, error: 2, message: None },);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -947,7 +969,7 @@ mod tests {
|
||||
// Ignores `message` field in `Module` variant.
|
||||
assert_eq!(
|
||||
Module { index: 1, error: 1, message: Some("foo") },
|
||||
Module { index: 1, error: 1, message: None},
|
||||
Module { index: 1, error: 1, message: None },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -971,17 +993,13 @@ mod tests {
|
||||
#[should_panic(expected = "Signature verification has not been called")]
|
||||
fn batching_still_finishes_when_not_called_directly() {
|
||||
let mut ext = sp_state_machine::BasicExternalities::default();
|
||||
ext.register_extension(
|
||||
sp_core::traits::TaskExecutorExt::new(sp_core::testing::TaskExecutor::new()),
|
||||
);
|
||||
ext.register_extension(sp_core::traits::TaskExecutorExt::new(
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
));
|
||||
|
||||
ext.execute_with(|| {
|
||||
let _batching = SignatureBatching::start();
|
||||
sp_io::crypto::sr25519_verify(
|
||||
&Default::default(),
|
||||
&Vec::new(),
|
||||
&Default::default(),
|
||||
);
|
||||
sp_io::crypto::sr25519_verify(&Default::default(), &Vec::new(), &Default::default());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -989,9 +1007,9 @@ mod tests {
|
||||
#[should_panic(expected = "Hey, I'm an error")]
|
||||
fn batching_does_not_panic_while_thread_is_already_panicking() {
|
||||
let mut ext = sp_state_machine::BasicExternalities::default();
|
||||
ext.register_extension(
|
||||
sp_core::traits::TaskExecutorExt::new(sp_core::testing::TaskExecutor::new()),
|
||||
);
|
||||
ext.register_extension(sp_core::traits::TaskExecutorExt::new(
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
));
|
||||
|
||||
ext.execute_with(|| {
|
||||
let _batching = SignatureBatching::start();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
//! MultiAddress type is a wrapper for multiple downstream account formats.
|
||||
|
||||
use codec::{Encode, Decode};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_std::vec::Vec;
|
||||
|
||||
/// A multi-format address wrapper for on-chain accounts.
|
||||
@@ -46,8 +46,10 @@ where
|
||||
use sp_core::hexdisplay::HexDisplay;
|
||||
match self {
|
||||
Self::Raw(inner) => write!(f, "MultiAddress::Raw({})", HexDisplay::from(inner)),
|
||||
Self::Address32(inner) => write!(f, "MultiAddress::Address32({})", HexDisplay::from(inner)),
|
||||
Self::Address20(inner) => write!(f, "MultiAddress::Address20({})", HexDisplay::from(inner)),
|
||||
Self::Address32(inner) =>
|
||||
write!(f, "MultiAddress::Address32({})", HexDisplay::from(inner)),
|
||||
Self::Address20(inner) =>
|
||||
write!(f, "MultiAddress::Address20({})", HexDisplay::from(inner)),
|
||||
_ => write!(f, "{:?}", self),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,17 +48,15 @@
|
||||
//! assert_eq!(body.error(), &None);
|
||||
//! ```
|
||||
|
||||
use sp_std::str;
|
||||
use sp_std::prelude::Vec;
|
||||
use sp_core::{
|
||||
offchain::{
|
||||
HttpError, HttpRequestId as RequestId, HttpRequestStatus as RequestStatus, Timestamp,
|
||||
},
|
||||
RuntimeDebug,
|
||||
};
|
||||
#[cfg(not(feature = "std"))]
|
||||
use sp_std::prelude::vec;
|
||||
use sp_core::RuntimeDebug;
|
||||
use sp_core::offchain::{
|
||||
Timestamp,
|
||||
HttpRequestId as RequestId,
|
||||
HttpRequestStatus as RequestStatus,
|
||||
HttpError,
|
||||
};
|
||||
use sp_std::{prelude::Vec, str};
|
||||
|
||||
/// Request method (HTTP verb)
|
||||
#[derive(Clone, PartialEq, Eq, RuntimeDebug)]
|
||||
@@ -103,10 +101,7 @@ mod header {
|
||||
impl Header {
|
||||
/// Creates new header given it's name and value.
|
||||
pub fn new(name: &str, value: &str) -> Self {
|
||||
Header {
|
||||
name: name.as_bytes().to_vec(),
|
||||
value: value.as_bytes().to_vec(),
|
||||
}
|
||||
Header { name: name.as_bytes().to_vec(), value: value.as_bytes().to_vec() }
|
||||
}
|
||||
|
||||
/// Returns the name of this header.
|
||||
@@ -166,13 +161,7 @@ impl<'a, T> Request<'a, T> {
|
||||
pub fn post(url: &'a str, body: T) -> Self {
|
||||
let req: Request = Request::default();
|
||||
|
||||
Request {
|
||||
url,
|
||||
body,
|
||||
method: Method::Post,
|
||||
headers: req.headers,
|
||||
deadline: req.deadline,
|
||||
}
|
||||
Request { url, body, method: Method::Post, headers: req.headers, deadline: req.deadline }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +202,7 @@ impl<'a, T: Default> Request<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I: AsRef<[u8]>, T: IntoIterator<Item=I>> Request<'a, T> {
|
||||
impl<'a, I: AsRef<[u8]>, T: IntoIterator<Item = I>> Request<'a, T> {
|
||||
/// Send the request and return a handle.
|
||||
///
|
||||
/// Err is returned in case the deadline is reached
|
||||
@@ -222,19 +211,13 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator<Item=I>> Request<'a, T> {
|
||||
let meta = &[];
|
||||
|
||||
// start an http request.
|
||||
let id = sp_io::offchain::http_request_start(
|
||||
self.method.as_ref(),
|
||||
self.url,
|
||||
meta,
|
||||
).map_err(|_| HttpError::IoError)?;
|
||||
let id = sp_io::offchain::http_request_start(self.method.as_ref(), self.url, meta)
|
||||
.map_err(|_| HttpError::IoError)?;
|
||||
|
||||
// add custom headers
|
||||
for header in &self.headers {
|
||||
sp_io::offchain::http_request_add_header(
|
||||
id,
|
||||
header.name(),
|
||||
header.value(),
|
||||
).map_err(|_| HttpError::IoError)?
|
||||
sp_io::offchain::http_request_add_header(id, header.name(), header.value())
|
||||
.map_err(|_| HttpError::IoError)?
|
||||
}
|
||||
|
||||
// write body
|
||||
@@ -245,9 +228,7 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator<Item=I>> Request<'a, T> {
|
||||
// finalize the request
|
||||
sp_io::offchain::http_request_write_body(id, &[], self.deadline)?;
|
||||
|
||||
Ok(PendingRequest {
|
||||
id,
|
||||
})
|
||||
Ok(PendingRequest { id })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,8 +266,13 @@ impl PendingRequest {
|
||||
|
||||
/// Attempts to wait for the request to finish,
|
||||
/// but will return `Err` in case the deadline is reached.
|
||||
pub fn try_wait(self, deadline: impl Into<Option<Timestamp>>) -> Result<HttpResult, PendingRequest> {
|
||||
Self::try_wait_all(vec![self], deadline).pop().expect("One request passed, one status received; qed")
|
||||
pub fn try_wait(
|
||||
self,
|
||||
deadline: impl Into<Option<Timestamp>>,
|
||||
) -> Result<HttpResult, PendingRequest> {
|
||||
Self::try_wait_all(vec![self], deadline)
|
||||
.pop()
|
||||
.expect("One request passed, one status received; qed")
|
||||
}
|
||||
|
||||
/// Wait for all provided requests.
|
||||
@@ -305,7 +291,7 @@ impl PendingRequest {
|
||||
/// Requests that are complete will resolve to an `Ok` others will return a `DeadlineReached` error.
|
||||
pub fn try_wait_all(
|
||||
requests: Vec<PendingRequest>,
|
||||
deadline: impl Into<Option<Timestamp>>
|
||||
deadline: impl Into<Option<Timestamp>>,
|
||||
) -> Vec<Result<HttpResult, PendingRequest>> {
|
||||
let ids = requests.iter().map(|r| r.id).collect::<Vec<_>>();
|
||||
let statuses = sp_io::offchain::http_response_wait(&ids, deadline.into());
|
||||
@@ -336,19 +322,13 @@ pub struct Response {
|
||||
|
||||
impl Response {
|
||||
fn new(id: RequestId, code: u16) -> Self {
|
||||
Self {
|
||||
id,
|
||||
code,
|
||||
headers: None,
|
||||
}
|
||||
Self { id, code, headers: None }
|
||||
}
|
||||
|
||||
/// Retrieve the headers for this response.
|
||||
pub fn headers(&mut self) -> &Headers {
|
||||
if self.headers.is_none() {
|
||||
self.headers = Some(
|
||||
Headers { raw: sp_io::offchain::http_response_headers(self.id) },
|
||||
);
|
||||
self.headers = Some(Headers { raw: sp_io::offchain::http_response_headers(self.id) });
|
||||
}
|
||||
self.headers.as_ref().expect("Headers were just set; qed")
|
||||
}
|
||||
@@ -363,7 +343,7 @@ impl Response {
|
||||
///
|
||||
/// Note that reading the body may return `None` in following cases:
|
||||
/// 1. Either the deadline you've set is reached (check via `#error`;
|
||||
/// In such case you can resume the reader by setting a new deadline)
|
||||
/// In such case you can resume the reader by setting a new deadline)
|
||||
/// 2. Or because of IOError. In such case the reader is not resumable and will keep
|
||||
/// returning `None`.
|
||||
/// 3. The body has been returned. The reader will keep returning `None`.
|
||||
@@ -423,32 +403,28 @@ impl Iterator for ResponseBody {
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.error.is_some() {
|
||||
return None;
|
||||
return None
|
||||
}
|
||||
|
||||
if self.filled_up_to.is_none() {
|
||||
let result = sp_io::offchain::http_response_read_body(
|
||||
self.id,
|
||||
&mut self.buffer,
|
||||
self.deadline);
|
||||
let result =
|
||||
sp_io::offchain::http_response_read_body(self.id, &mut self.buffer, self.deadline);
|
||||
match result {
|
||||
Err(e) => {
|
||||
self.error = Some(e);
|
||||
return None;
|
||||
}
|
||||
Ok(0) => {
|
||||
return None;
|
||||
}
|
||||
return None
|
||||
},
|
||||
Ok(0) => return None,
|
||||
Ok(size) => {
|
||||
self.position = 0;
|
||||
self.filled_up_to = Some(size as usize);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if Some(self.position) == self.filled_up_to {
|
||||
self.filled_up_to = None;
|
||||
return self.next();
|
||||
return self.next()
|
||||
}
|
||||
|
||||
let result = self.buffer[self.position];
|
||||
@@ -508,7 +484,8 @@ impl<'a> HeadersIterator<'a> {
|
||||
///
|
||||
/// Note that you have to call `next` prior to calling this
|
||||
pub fn current(&self) -> Option<(&str, &str)> {
|
||||
self.collection.get(self.index?)
|
||||
self.collection
|
||||
.get(self.index?)
|
||||
.map(|val| (str::from_utf8(&val.0).unwrap_or(""), str::from_utf8(&val.1).unwrap_or("")))
|
||||
}
|
||||
}
|
||||
@@ -516,11 +493,8 @@ impl<'a> HeadersIterator<'a> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sp_core::offchain::{testing, OffchainWorkerExt};
|
||||
use sp_io::TestExternalities;
|
||||
use sp_core::offchain::{
|
||||
OffchainWorkerExt,
|
||||
testing,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn should_send_a_basic_request_and_get_response() {
|
||||
@@ -530,10 +504,7 @@ mod tests {
|
||||
|
||||
t.execute_with(|| {
|
||||
let request: Request = Request::get("http://localhost:1234");
|
||||
let pending = request
|
||||
.add_header("X-Auth", "hunter2")
|
||||
.send()
|
||||
.unwrap();
|
||||
let pending = request.add_header("X-Auth", "hunter2").send().unwrap();
|
||||
// make sure it's sent correctly
|
||||
state.write().fulfill_pending_request(
|
||||
0,
|
||||
|
||||
@@ -44,7 +44,7 @@ pub enum MutateStorageError<T, E> {
|
||||
/// The function given to us to create the value to be stored failed.
|
||||
/// May be used to signal that having looked at the existing value,
|
||||
/// they don't want to mutate it.
|
||||
ValueFunctionFailed(E)
|
||||
ValueFunctionFailed(E),
|
||||
}
|
||||
|
||||
impl<'a> StorageValueRef<'a> {
|
||||
@@ -64,9 +64,7 @@ impl<'a> StorageValueRef<'a> {
|
||||
/// if you happen to write a `get-check-set` pattern you should most likely
|
||||
/// be using `mutate` instead.
|
||||
pub fn set(&self, value: &impl codec::Encode) {
|
||||
value.using_encoded(|val| {
|
||||
sp_io::offchain::local_storage_set(self.kind, self.key, val)
|
||||
})
|
||||
value.using_encoded(|val| sp_io::offchain::local_storage_set(self.kind, self.key, val))
|
||||
}
|
||||
|
||||
/// Remove the associated value from the storage.
|
||||
@@ -83,8 +81,7 @@ impl<'a> StorageValueRef<'a> {
|
||||
/// Returns an error if the value could not be decoded.
|
||||
pub fn get<T: codec::Decode>(&self) -> Result<Option<T>, StorageRetrievalError> {
|
||||
sp_io::offchain::local_storage_get(self.kind, self.key)
|
||||
.map(|val| T::decode(&mut &*val)
|
||||
.map_err(|_| StorageRetrievalError::Undecodable))
|
||||
.map(|val| T::decode(&mut &*val).map_err(|_| StorageRetrievalError::Undecodable))
|
||||
.transpose()
|
||||
}
|
||||
|
||||
@@ -98,26 +95,22 @@ impl<'a> StorageValueRef<'a> {
|
||||
/// 2. `Err(MutateStorageError::ConcurrentModification(T))` in case the value was calculated
|
||||
/// by the passed closure `mutate_val`, but it could not be stored.
|
||||
/// 3. `Err(MutateStorageError::ValueFunctionFailed(_))` in case `mutate_val` returns an error.
|
||||
pub fn mutate<T, E, F>(&self, mutate_val: F) -> Result<T, MutateStorageError<T,E>> where
|
||||
pub fn mutate<T, E, F>(&self, mutate_val: F) -> Result<T, MutateStorageError<T, E>>
|
||||
where
|
||||
T: codec::Codec,
|
||||
F: FnOnce(Result<Option<T>, StorageRetrievalError>) -> Result<T, E>
|
||||
F: FnOnce(Result<Option<T>, StorageRetrievalError>) -> Result<T, E>,
|
||||
{
|
||||
let value = sp_io::offchain::local_storage_get(self.kind, self.key);
|
||||
let decoded = value.as_deref()
|
||||
.map(|mut bytes| {
|
||||
T::decode(&mut bytes)
|
||||
.map_err(|_| StorageRetrievalError::Undecodable)
|
||||
}).transpose();
|
||||
let decoded = value
|
||||
.as_deref()
|
||||
.map(|mut bytes| T::decode(&mut bytes).map_err(|_| StorageRetrievalError::Undecodable))
|
||||
.transpose();
|
||||
|
||||
let val = mutate_val(decoded).map_err(|err| MutateStorageError::ValueFunctionFailed(err))?;
|
||||
let val =
|
||||
mutate_val(decoded).map_err(|err| MutateStorageError::ValueFunctionFailed(err))?;
|
||||
|
||||
let set = val.using_encoded(|new_val| {
|
||||
sp_io::offchain::local_storage_compare_and_set(
|
||||
self.kind,
|
||||
self.key,
|
||||
value,
|
||||
new_val,
|
||||
)
|
||||
sp_io::offchain::local_storage_compare_and_set(self.kind, self.key, value, new_val)
|
||||
});
|
||||
if set {
|
||||
Ok(val)
|
||||
@@ -130,11 +123,8 @@ impl<'a> StorageValueRef<'a> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sp_core::offchain::{testing, OffchainDbExt};
|
||||
use sp_io::TestExternalities;
|
||||
use sp_core::offchain::{
|
||||
OffchainDbExt,
|
||||
testing,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn should_set_and_get() {
|
||||
@@ -151,10 +141,7 @@ mod tests {
|
||||
|
||||
assert_eq!(val.get::<u32>(), Ok(Some(15_u32)));
|
||||
assert_eq!(val.get::<Vec<u8>>(), Err(StorageRetrievalError::Undecodable));
|
||||
assert_eq!(
|
||||
state.read().persistent_storage.get(b"testval"),
|
||||
Some(vec![15_u8, 0, 0, 0])
|
||||
);
|
||||
assert_eq!(state.read().persistent_storage.get(b"testval"), Some(vec![15_u8, 0, 0, 0]));
|
||||
})
|
||||
}
|
||||
|
||||
@@ -174,10 +161,7 @@ mod tests {
|
||||
});
|
||||
assert_eq!(result, Ok(16_u32));
|
||||
assert_eq!(val.get::<u32>(), Ok(Some(16_u32)));
|
||||
assert_eq!(
|
||||
state.read().persistent_storage.get(b"testval"),
|
||||
Some(vec![16_u8, 0, 0, 0])
|
||||
);
|
||||
assert_eq!(state.read().persistent_storage.get(b"testval"), Some(vec![16_u8, 0, 0, 0]));
|
||||
|
||||
// mutate again, but this time early-exit.
|
||||
let res = val.mutate::<u32, (), _>(|val| {
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
//! # use codec::{Decode, Encode, Codec};
|
||||
//! // in your off-chain worker code
|
||||
//! use sp_runtime::offchain::{
|
||||
//! storage::StorageValueRef,
|
||||
//! storage_lock::{StorageLock, Time},
|
||||
//! storage::StorageValueRef,
|
||||
//! storage_lock::{StorageLock, Time},
|
||||
//! };
|
||||
//!
|
||||
//! fn append_to_in_storage_vec<'a, T>(key: &'a [u8], _: T) where T: Codec {
|
||||
@@ -61,8 +61,10 @@
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use crate::offchain::storage::{StorageRetrievalError, MutateStorageError, StorageValueRef};
|
||||
use crate::traits::BlockNumberProvider;
|
||||
use crate::{
|
||||
offchain::storage::{MutateStorageError, StorageRetrievalError, StorageValueRef},
|
||||
traits::BlockNumberProvider,
|
||||
};
|
||||
use codec::{Codec, Decode, Encode};
|
||||
use sp_core::offchain::{Duration, Timestamp};
|
||||
use sp_io::offchain;
|
||||
@@ -115,9 +117,7 @@ pub struct Time {
|
||||
|
||||
impl Default for Time {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
expiration_duration: STORAGE_LOCK_DEFAULT_EXPIRY_DURATION,
|
||||
}
|
||||
Self { expiration_duration: STORAGE_LOCK_DEFAULT_EXPIRY_DURATION }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +157,7 @@ pub struct BlockAndTimeDeadline<B: BlockNumberProvider> {
|
||||
|
||||
impl<B: BlockNumberProvider> Clone for BlockAndTimeDeadline<B> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
block_number: self.block_number.clone(),
|
||||
timestamp: self.timestamp,
|
||||
}
|
||||
Self { block_number: self.block_number.clone(), timestamp: self.timestamp }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +172,8 @@ impl<B: BlockNumberProvider> Default for BlockAndTimeDeadline<B> {
|
||||
}
|
||||
|
||||
impl<B: BlockNumberProvider> fmt::Debug for BlockAndTimeDeadline<B>
|
||||
where <B as BlockNumberProvider>::BlockNumber: fmt::Debug
|
||||
where
|
||||
<B as BlockNumberProvider>::BlockNumber: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("BlockAndTimeDeadline")
|
||||
@@ -225,8 +223,8 @@ impl<B: BlockNumberProvider> Lockable for BlockAndTime<B> {
|
||||
type Deadline = BlockAndTimeDeadline<B>;
|
||||
|
||||
fn deadline(&self) -> Self::Deadline {
|
||||
let block_number = <B as BlockNumberProvider>::current_block_number()
|
||||
+ self.expiration_block_number_offset.into();
|
||||
let block_number = <B as BlockNumberProvider>::current_block_number() +
|
||||
self.expiration_block_number_offset.into();
|
||||
BlockAndTimeDeadline {
|
||||
timestamp: offchain::timestamp().add(self.expiration_duration),
|
||||
block_number,
|
||||
@@ -234,8 +232,8 @@ impl<B: BlockNumberProvider> Lockable for BlockAndTime<B> {
|
||||
}
|
||||
|
||||
fn has_expired(deadline: &Self::Deadline) -> bool {
|
||||
offchain::timestamp() > deadline.timestamp
|
||||
&& <B as BlockNumberProvider>::current_block_number() > deadline.block_number
|
||||
offchain::timestamp() > deadline.timestamp &&
|
||||
<B as BlockNumberProvider>::current_block_number() > deadline.block_number
|
||||
}
|
||||
|
||||
fn snooze(deadline: &Self::Deadline) {
|
||||
@@ -271,10 +269,7 @@ impl<'a, L: Lockable + Default> StorageLock<'a, L> {
|
||||
impl<'a, L: Lockable> StorageLock<'a, L> {
|
||||
/// Create a new storage lock with an explicit instance of a lockable `L`.
|
||||
pub fn with_lockable(key: &'a [u8], lockable: L) -> Self {
|
||||
Self {
|
||||
value_ref: StorageValueRef::<'a>::persistent(key),
|
||||
lockable,
|
||||
}
|
||||
Self { value_ref: StorageValueRef::<'a>::persistent(key), lockable }
|
||||
}
|
||||
|
||||
/// Extend active lock's deadline
|
||||
@@ -398,9 +393,7 @@ impl<'a> StorageLock<'a, Time> {
|
||||
pub fn with_deadline(key: &'a [u8], expiration_duration: Duration) -> Self {
|
||||
Self {
|
||||
value_ref: StorageValueRef::<'a>::persistent(key),
|
||||
lockable: Time {
|
||||
expiration_duration,
|
||||
},
|
||||
lockable: Time { expiration_duration },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -443,7 +436,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sp_core::offchain::{testing, OffchainWorkerExt, OffchainDbExt};
|
||||
use sp_core::offchain::{testing, OffchainDbExt, OffchainWorkerExt};
|
||||
use sp_io::TestExternalities;
|
||||
|
||||
const VAL_1: u32 = 0u32;
|
||||
|
||||
@@ -57,11 +57,7 @@ impl log::Log for RuntimeLogger {
|
||||
let mut w = sp_std::Writer::default();
|
||||
let _ = ::core::write!(&mut w, "{}", record.args());
|
||||
|
||||
sp_io::logging::log(
|
||||
record.level().into(),
|
||||
record.target(),
|
||||
w.inner(),
|
||||
);
|
||||
sp_io::logging::log(record.level().into(), record.target(), w.inner());
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
@@ -69,12 +65,12 @@ impl log::Log for RuntimeLogger {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use substrate_test_runtime_client::{
|
||||
ExecutionStrategy, TestClientBuilderExt, DefaultTestClientBuilderExt,
|
||||
TestClientBuilder, runtime::TestAPI,
|
||||
};
|
||||
use sp_api::{ProvideRuntimeApi, BlockId};
|
||||
use sp_api::{BlockId, ProvideRuntimeApi};
|
||||
use std::{env, str::FromStr};
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::TestAPI, DefaultTestClientBuilderExt, ExecutionStrategy, TestClientBuilder,
|
||||
TestClientBuilderExt,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn ensure_runtime_logger_respects_host_max_log_level() {
|
||||
@@ -83,7 +79,8 @@ mod tests {
|
||||
log::set_max_level(log::LevelFilter::from_str(&env::var("RUST_LOG").unwrap()).unwrap());
|
||||
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm).build();
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(0);
|
||||
runtime_api.do_trace_log(&block_id).expect("Logging should not fail");
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use codec::{Encode, Decode};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_core::RuntimeDebug;
|
||||
use sp_std::vec::Vec;
|
||||
|
||||
@@ -47,7 +47,6 @@ macro_rules! format_runtime_string {
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
impl From<&'static str> for RuntimeString {
|
||||
fn from(data: &'static str) -> Self {
|
||||
Self::Borrowed(data)
|
||||
@@ -130,5 +129,7 @@ impl<'de> serde::Deserialize<'de> for RuntimeString {
|
||||
/// Create a const [`RuntimeString`].
|
||||
#[macro_export]
|
||||
macro_rules! create_runtime_str {
|
||||
( $y:expr ) => {{ $crate::RuntimeString::Borrowed($y) }}
|
||||
( $y:expr ) => {{
|
||||
$crate::RuntimeString::Borrowed($y)
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -17,18 +17,27 @@
|
||||
|
||||
//! Testing utilities.
|
||||
|
||||
use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer};
|
||||
use std::{fmt::{self, Debug}, ops::Deref, cell::RefCell};
|
||||
use crate::codec::{Codec, Encode, Decode};
|
||||
use crate::traits::{
|
||||
self, Checkable, Applyable, BlakeTwo256, OpaqueKeys,
|
||||
SignedExtension, Dispatchable, DispatchInfoOf, PostDispatchInfoOf,
|
||||
use crate::{
|
||||
codec::{Codec, Decode, Encode},
|
||||
generic,
|
||||
traits::{
|
||||
self, Applyable, BlakeTwo256, Checkable, DispatchInfoOf, Dispatchable, OpaqueKeys,
|
||||
PostDispatchInfoOf, SignedExtension, ValidateUnsigned,
|
||||
},
|
||||
transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
|
||||
ApplyExtrinsicResultWithInfo, CryptoTypeId, KeyTypeId,
|
||||
};
|
||||
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use sp_core::{
|
||||
crypto::{key_types, CryptoType, Dummy, Public},
|
||||
U256,
|
||||
};
|
||||
pub use sp_core::{sr25519, H256};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fmt::{self, Debug},
|
||||
ops::Deref,
|
||||
};
|
||||
use crate::traits::ValidateUnsigned;
|
||||
use crate::{generic, KeyTypeId, CryptoTypeId, ApplyExtrinsicResultWithInfo};
|
||||
pub use sp_core::{H256, sr25519};
|
||||
use sp_core::{crypto::{CryptoType, Dummy, key_types, Public}, U256};
|
||||
use crate::transaction_validity::{TransactionValidity, TransactionValidityError, TransactionSource};
|
||||
|
||||
/// A dummy type which can be used instead of regular cryptographic primitives.
|
||||
///
|
||||
@@ -36,7 +45,20 @@ use crate::transaction_validity::{TransactionValidity, TransactionValidityError,
|
||||
/// 2. Can be converted to any `Public` key.
|
||||
/// 3. Implements `RuntimeAppPublic` so it can be used instead of regular application-specific
|
||||
/// crypto.
|
||||
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize, PartialOrd, Ord)]
|
||||
#[derive(
|
||||
Default,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Clone,
|
||||
Encode,
|
||||
Decode,
|
||||
Debug,
|
||||
Hash,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
)]
|
||||
pub struct UintAuthorityId(pub u64);
|
||||
|
||||
impl From<u64> for UintAuthorityId {
|
||||
@@ -68,7 +90,10 @@ impl AsRef<[u8]> for UintAuthorityId {
|
||||
// Unsafe, i know, but it's test code and it's just there because it's really convenient to
|
||||
// keep `UintAuthorityId` as a u64 under the hood.
|
||||
unsafe {
|
||||
std::slice::from_raw_parts(&self.0 as *const u64 as *const _, std::mem::size_of::<u64>())
|
||||
std::slice::from_raw_parts(
|
||||
&self.0 as *const u64 as *const _,
|
||||
std::mem::size_of::<u64>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +105,7 @@ thread_local! {
|
||||
|
||||
impl UintAuthorityId {
|
||||
/// Set the list of keys returned by the runtime call for all keys of that type.
|
||||
pub fn set_all_keys<T: Into<UintAuthorityId>>(keys: impl IntoIterator<Item=T>) {
|
||||
pub fn set_all_keys<T: Into<UintAuthorityId>>(keys: impl IntoIterator<Item = T>) {
|
||||
ALL_KEYS.with(|l| *l.borrow_mut() = keys.into_iter().map(Into::into).collect())
|
||||
}
|
||||
}
|
||||
@@ -180,7 +205,8 @@ impl Header {
|
||||
pub struct ExtrinsicWrapper<Xt>(Xt);
|
||||
|
||||
impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt>
|
||||
where Xt: parity_util_mem::MallocSizeOf
|
||||
where
|
||||
Xt: parity_util_mem::MallocSizeOf,
|
||||
{
|
||||
type Call = ();
|
||||
type SignaturePayload = ();
|
||||
@@ -191,7 +217,10 @@ where Xt: parity_util_mem::MallocSizeOf
|
||||
}
|
||||
|
||||
impl<Xt: Encode> serde::Serialize for ExtrinsicWrapper<Xt> {
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: ::serde::Serializer,
|
||||
{
|
||||
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
|
||||
}
|
||||
}
|
||||
@@ -219,8 +248,9 @@ pub struct Block<Xt> {
|
||||
pub extrinsics: Vec<Xt>,
|
||||
}
|
||||
|
||||
impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + Clone + Eq + Debug + traits::Extrinsic> traits::Block
|
||||
for Block<Xt>
|
||||
impl<
|
||||
Xt: 'static + Codec + Sized + Send + Sync + Serialize + Clone + Eq + Debug + traits::Extrinsic,
|
||||
> traits::Block for Block<Xt>
|
||||
{
|
||||
type Extrinsic = Xt;
|
||||
type Header = Header;
|
||||
@@ -243,7 +273,10 @@ impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + Clone + Eq + Debug
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Xt> Deserialize<'a> for Block<Xt> where Block<Xt>: Decode {
|
||||
impl<'a, Xt> Deserialize<'a> for Block<Xt>
|
||||
where
|
||||
Block<Xt>: Decode,
|
||||
{
|
||||
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
|
||||
let r = <Vec<u8>>::deserialize(de)?;
|
||||
Decode::decode(&mut &r[..])
|
||||
@@ -273,8 +306,14 @@ impl<Call, Extra> TestXt<Call, Extra> {
|
||||
// Non-opaque extrinsics always 0.
|
||||
parity_util_mem::malloc_size_of_is_0!(any: TestXt<Call, Extra>);
|
||||
|
||||
impl<Call, Extra> Serialize for TestXt<Call, Extra> where TestXt<Call, Extra>: Encode {
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||
impl<Call, Extra> Serialize for TestXt<Call, Extra>
|
||||
where
|
||||
TestXt<Call, Extra>: Encode,
|
||||
{
|
||||
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
|
||||
}
|
||||
}
|
||||
@@ -287,7 +326,9 @@ impl<Call, Extra> Debug for TestXt<Call, Extra> {
|
||||
|
||||
impl<Call: Codec + Sync + Send, Context, Extra> Checkable<Context> for TestXt<Call, Extra> {
|
||||
type Checked = Self;
|
||||
fn check(self, _: &Context) -> Result<Self::Checked, TransactionValidityError> { Ok(self) }
|
||||
fn check(self, _: &Context) -> Result<Self::Checked, TransactionValidityError> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call: Codec + Sync + Send, Extra> traits::Extrinsic for TestXt<Call, Extra> {
|
||||
@@ -303,23 +344,26 @@ impl<Call: Codec + Sync + Send, Extra> traits::Extrinsic for TestXt<Call, Extra>
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call, Extra> traits::ExtrinsicMetadata for TestXt<Call, Extra> where
|
||||
impl<Call, Extra> traits::ExtrinsicMetadata for TestXt<Call, Extra>
|
||||
where
|
||||
Call: Codec + Sync + Send,
|
||||
Extra: SignedExtension<AccountId=u64, Call=Call>,
|
||||
Extra: SignedExtension<AccountId = u64, Call = Call>,
|
||||
{
|
||||
type SignedExtensions = Extra;
|
||||
const VERSION: u8 = 0u8;
|
||||
}
|
||||
|
||||
impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra> where
|
||||
Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Dispatchable<Origin=Origin>,
|
||||
Extra: SignedExtension<AccountId=u64, Call=Call>,
|
||||
impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra>
|
||||
where
|
||||
Call:
|
||||
'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Dispatchable<Origin = Origin>,
|
||||
Extra: SignedExtension<AccountId = u64, Call = Call>,
|
||||
Origin: From<Option<u64>>,
|
||||
{
|
||||
type Call = Call;
|
||||
|
||||
/// Checks to see if this is a valid *transaction*. It returns information on it if so.
|
||||
fn validate<U: ValidateUnsigned<Call=Self::Call>>(
|
||||
fn validate<U: ValidateUnsigned<Call = Self::Call>>(
|
||||
&self,
|
||||
source: TransactionSource,
|
||||
info: &DispatchInfoOf<Self::Call>,
|
||||
@@ -336,7 +380,7 @@ impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra> where
|
||||
|
||||
/// Executes all necessary logic needed prior to dispatch and deconstructs into function call,
|
||||
/// index and sender.
|
||||
fn apply<U: ValidateUnsigned<Call=Self::Call>>(
|
||||
fn apply<U: ValidateUnsigned<Call = Self::Call>>(
|
||||
self,
|
||||
info: &DispatchInfoOf<Self::Call>,
|
||||
len: usize,
|
||||
|
||||
@@ -17,29 +17,36 @@
|
||||
|
||||
//! Primitives for the runtime modules.
|
||||
|
||||
use sp_std::prelude::*;
|
||||
use sp_std::{self, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug};
|
||||
use crate::{
|
||||
codec::{Codec, Decode, Encode, MaxEncodedLen},
|
||||
generic::{Digest, DigestItem},
|
||||
transaction_validity::{
|
||||
TransactionSource, TransactionValidity, TransactionValidityError, UnknownTransaction,
|
||||
ValidTransaction,
|
||||
},
|
||||
DispatchResult,
|
||||
};
|
||||
use impl_trait_for_tuples::impl_for_tuples;
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use sp_application_crypto::AppKey;
|
||||
pub use sp_arithmetic::traits::{
|
||||
AtLeast32Bit, AtLeast32BitUnsigned, Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedShl,
|
||||
CheckedShr, CheckedSub, IntegerSquareRoot, One, SaturatedConversion, Saturating,
|
||||
UniqueSaturatedFrom, UniqueSaturatedInto, Zero,
|
||||
};
|
||||
use sp_core::{self, Hasher, RuntimeDebug, TypeId};
|
||||
use sp_std::{
|
||||
self,
|
||||
convert::{TryFrom, TryInto},
|
||||
fmt::Debug,
|
||||
marker::PhantomData,
|
||||
prelude::*,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use std::fmt::Display;
|
||||
#[cfg(feature = "std")]
|
||||
use std::str::FromStr;
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Deserialize, de::DeserializeOwned};
|
||||
use sp_core::{self, Hasher, TypeId, RuntimeDebug};
|
||||
use crate::codec::{Codec, Encode, Decode, MaxEncodedLen};
|
||||
use crate::transaction_validity::{
|
||||
ValidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
|
||||
UnknownTransaction,
|
||||
};
|
||||
use crate::generic::{Digest, DigestItem};
|
||||
pub use sp_arithmetic::traits::{
|
||||
AtLeast32Bit, AtLeast32BitUnsigned, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating,
|
||||
SaturatedConversion, Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
|
||||
CheckedShl, CheckedShr, IntegerSquareRoot
|
||||
};
|
||||
use sp_application_crypto::AppKey;
|
||||
use impl_trait_for_tuples::impl_for_tuples;
|
||||
use crate::DispatchResult;
|
||||
|
||||
/// A lazy value.
|
||||
pub trait Lazy<T: ?Sized> {
|
||||
@@ -50,7 +57,9 @@ pub trait Lazy<T: ?Sized> {
|
||||
}
|
||||
|
||||
impl<'a> Lazy<[u8]> for &'a [u8] {
|
||||
fn get(&mut self) -> &[u8] { &**self }
|
||||
fn get(&mut self) -> &[u8] {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
/// Some type that is able to be collapsed into an account ID. It is not possible to recreate the
|
||||
@@ -64,17 +73,23 @@ pub trait IdentifyAccount {
|
||||
|
||||
impl IdentifyAccount for sp_core::ed25519::Public {
|
||||
type AccountId = Self;
|
||||
fn into_account(self) -> Self { self }
|
||||
fn into_account(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl IdentifyAccount for sp_core::sr25519::Public {
|
||||
type AccountId = Self;
|
||||
fn into_account(self) -> Self { self }
|
||||
fn into_account(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl IdentifyAccount for sp_core::ecdsa::Public {
|
||||
type AccountId = Self;
|
||||
fn into_account(self) -> Self { self }
|
||||
fn into_account(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Means of signature verification.
|
||||
@@ -84,7 +99,11 @@ pub trait Verify {
|
||||
/// Verify a signature.
|
||||
///
|
||||
/// Return `true` if signature is valid for the value.
|
||||
fn verify<L: Lazy<[u8]>>(&self, msg: L, signer: &<Self::Signer as IdentifyAccount>::AccountId) -> bool;
|
||||
fn verify<L: Lazy<[u8]>>(
|
||||
&self,
|
||||
msg: L,
|
||||
signer: &<Self::Signer as IdentifyAccount>::AccountId,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
impl Verify for sp_core::ed25519::Signature {
|
||||
@@ -125,19 +144,27 @@ pub trait AppVerify {
|
||||
}
|
||||
|
||||
impl<
|
||||
S: Verify<Signer = <<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic> + From<T>,
|
||||
T: sp_application_crypto::Wraps<Inner=S> + sp_application_crypto::AppKey + sp_application_crypto::AppSignature +
|
||||
AsRef<S> + AsMut<S> + From<S>,
|
||||
> AppVerify for T where
|
||||
S: Verify<Signer = <<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic>
|
||||
+ From<T>,
|
||||
T: sp_application_crypto::Wraps<Inner = S>
|
||||
+ sp_application_crypto::AppKey
|
||||
+ sp_application_crypto::AppSignature
|
||||
+ AsRef<S>
|
||||
+ AsMut<S>
|
||||
+ From<S>,
|
||||
> AppVerify for T
|
||||
where
|
||||
<S as Verify>::Signer: IdentifyAccount<AccountId = <S as Verify>::Signer>,
|
||||
<<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic:
|
||||
IdentifyAccount<AccountId = <<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic>,
|
||||
<<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic: IdentifyAccount<
|
||||
AccountId = <<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic,
|
||||
>,
|
||||
{
|
||||
type AccountId = <T as AppKey>::Public;
|
||||
fn verify<L: Lazy<[u8]>>(&self, msg: L, signer: &<T as AppKey>::Public) -> bool {
|
||||
use sp_application_crypto::IsWrappedBy;
|
||||
let inner: &S = self.as_ref();
|
||||
let inner_pubkey = <<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic::from_ref(&signer);
|
||||
let inner_pubkey =
|
||||
<<T as AppKey>::Public as sp_application_crypto::AppPublic>::Generic::from_ref(&signer);
|
||||
Verify::verify(inner, msg, inner_pubkey)
|
||||
}
|
||||
}
|
||||
@@ -198,14 +225,20 @@ pub struct IdentityLookup<T>(PhantomData<T>);
|
||||
impl<T: Codec + Clone + PartialEq + Debug> StaticLookup for IdentityLookup<T> {
|
||||
type Source = T;
|
||||
type Target = T;
|
||||
fn lookup(x: T) -> Result<T, LookupError> { Ok(x) }
|
||||
fn unlookup(x: T) -> T { x }
|
||||
fn lookup(x: T) -> Result<T, LookupError> {
|
||||
Ok(x)
|
||||
}
|
||||
fn unlookup(x: T) -> T {
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Lookup for IdentityLookup<T> {
|
||||
type Source = T;
|
||||
type Target = T;
|
||||
fn lookup(&self, x: T) -> Result<T, LookupError> { Ok(x) }
|
||||
fn lookup(&self, x: T) -> Result<T, LookupError> {
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
/// A lookup implementation returning the `AccountId` from a `MultiAddress`.
|
||||
@@ -253,19 +286,25 @@ pub trait Convert<A, B> {
|
||||
}
|
||||
|
||||
impl<A, B: Default> Convert<A, B> for () {
|
||||
fn convert(_: A) -> B { Default::default() }
|
||||
fn convert(_: A) -> B {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// A structure that performs identity conversion.
|
||||
pub struct Identity;
|
||||
impl<T> Convert<T, T> for Identity {
|
||||
fn convert(a: T) -> T { a }
|
||||
fn convert(a: T) -> T {
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
/// A structure that performs standard conversion using the standard Rust conversion traits.
|
||||
pub struct ConvertInto;
|
||||
impl<A, B: From<A>> Convert<A, B> for ConvertInto {
|
||||
fn convert(a: A) -> B { a.into() }
|
||||
fn convert(a: A) -> B {
|
||||
a.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience type to work around the highly unergonomic syntax needed
|
||||
@@ -277,7 +316,10 @@ pub trait CheckedConversion {
|
||||
/// This just uses `TryFrom` internally but with this
|
||||
/// variant you can provide the destination type using turbofish syntax
|
||||
/// in case Rust happens not to assume the correct type.
|
||||
fn checked_from<T>(t: T) -> Option<Self> where Self: TryFrom<T> {
|
||||
fn checked_from<T>(t: T) -> Option<Self>
|
||||
where
|
||||
Self: TryFrom<T>,
|
||||
{
|
||||
<Self as TryFrom<T>>::try_from(t).ok()
|
||||
}
|
||||
/// Consume self to return `Some` equivalent value of `Option<T>`.
|
||||
@@ -285,7 +327,10 @@ pub trait CheckedConversion {
|
||||
/// This just uses `TryInto` internally but with this
|
||||
/// variant you can provide the destination type using turbofish syntax
|
||||
/// in case Rust happens not to assume the correct type.
|
||||
fn checked_into<T>(self) -> Option<T> where Self: TryInto<T> {
|
||||
fn checked_into<T>(self) -> Option<T>
|
||||
where
|
||||
Self: TryInto<T>,
|
||||
{
|
||||
<Self as TryInto<T>>::try_into(self).ok()
|
||||
}
|
||||
}
|
||||
@@ -310,11 +355,17 @@ macro_rules! impl_scale {
|
||||
($self:ty, $other:ty) => {
|
||||
impl Scale<$other> for $self {
|
||||
type Output = Self;
|
||||
fn mul(self, other: $other) -> Self::Output { self * (other as Self) }
|
||||
fn div(self, other: $other) -> Self::Output { self / (other as Self) }
|
||||
fn rem(self, other: $other) -> Self::Output { self % (other as Self) }
|
||||
fn mul(self, other: $other) -> Self::Output {
|
||||
self * (other as Self)
|
||||
}
|
||||
fn div(self, other: $other) -> Self::Output {
|
||||
self / (other as Self)
|
||||
}
|
||||
fn rem(self, other: $other) -> Self::Output {
|
||||
self % (other as Self)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
impl_scale!(u128, u128);
|
||||
impl_scale!(u128, u64);
|
||||
@@ -343,31 +394,57 @@ pub trait Clear {
|
||||
}
|
||||
|
||||
impl<T: Default + Eq + PartialEq> Clear for T {
|
||||
fn is_clear(&self) -> bool { *self == Self::clear() }
|
||||
fn clear() -> Self { Default::default() }
|
||||
fn is_clear(&self) -> bool {
|
||||
*self == Self::clear()
|
||||
}
|
||||
fn clear() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// A meta trait for all bit ops.
|
||||
pub trait SimpleBitOps:
|
||||
Sized + Clear +
|
||||
sp_std::ops::BitOr<Self, Output = Self> +
|
||||
sp_std::ops::BitXor<Self, Output = Self> +
|
||||
sp_std::ops::BitAnd<Self, Output = Self>
|
||||
{}
|
||||
impl<T:
|
||||
Sized + Clear +
|
||||
sp_std::ops::BitOr<Self, Output = Self> +
|
||||
sp_std::ops::BitXor<Self, Output = Self> +
|
||||
sp_std::ops::BitAnd<Self, Output = Self>
|
||||
> SimpleBitOps for T {}
|
||||
Sized
|
||||
+ Clear
|
||||
+ sp_std::ops::BitOr<Self, Output = Self>
|
||||
+ sp_std::ops::BitXor<Self, Output = Self>
|
||||
+ sp_std::ops::BitAnd<Self, Output = Self>
|
||||
{
|
||||
}
|
||||
impl<
|
||||
T: Sized
|
||||
+ Clear
|
||||
+ sp_std::ops::BitOr<Self, Output = Self>
|
||||
+ sp_std::ops::BitXor<Self, Output = Self>
|
||||
+ sp_std::ops::BitAnd<Self, Output = Self>,
|
||||
> SimpleBitOps for T
|
||||
{
|
||||
}
|
||||
|
||||
/// Abstraction around hashing
|
||||
// Stupid bug in the Rust compiler believes derived
|
||||
// traits must be fulfilled by all type parameters.
|
||||
pub trait Hash: 'static + MaybeSerializeDeserialize + Debug + Clone + Eq + PartialEq + Hasher<Out = <Self as Hash>::Output> {
|
||||
pub trait Hash:
|
||||
'static
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug
|
||||
+ Clone
|
||||
+ Eq
|
||||
+ PartialEq
|
||||
+ Hasher<Out = <Self as Hash>::Output>
|
||||
{
|
||||
/// The hash type produced.
|
||||
type Output: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash
|
||||
+ AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode + MaxEncodedLen;
|
||||
type Output: Member
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug
|
||||
+ sp_std::hash::Hash
|
||||
+ AsRef<[u8]>
|
||||
+ AsMut<[u8]>
|
||||
+ Copy
|
||||
+ Default
|
||||
+ Encode
|
||||
+ Decode
|
||||
+ MaxEncodedLen;
|
||||
|
||||
/// Produce the hash of some byte-slice.
|
||||
fn hash(s: &[u8]) -> Self::Output {
|
||||
@@ -469,7 +546,10 @@ impl CheckEqual for sp_core::H256 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: PartialEq + Eq + Debug> CheckEqual for super::generic::DigestItem<H> where H: Encode {
|
||||
impl<H: PartialEq + Eq + Debug> CheckEqual for super::generic::DigestItem<H>
|
||||
where
|
||||
H: Encode,
|
||||
{
|
||||
#[cfg(feature = "std")]
|
||||
fn check_equal(&self, other: &Self) {
|
||||
if self != other {
|
||||
@@ -523,16 +603,33 @@ pub trait IsMember<MemberId> {
|
||||
///
|
||||
/// You can also create a `new` one from those fields.
|
||||
pub trait Header:
|
||||
Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug +
|
||||
MaybeMallocSizeOf + 'static
|
||||
Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + MaybeMallocSizeOf + 'static
|
||||
{
|
||||
/// Header number.
|
||||
type Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Copy +
|
||||
MaybeDisplay + AtLeast32BitUnsigned + Codec + sp_std::str::FromStr + MaybeMallocSizeOf;
|
||||
type Number: Member
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug
|
||||
+ sp_std::hash::Hash
|
||||
+ Copy
|
||||
+ MaybeDisplay
|
||||
+ AtLeast32BitUnsigned
|
||||
+ Codec
|
||||
+ sp_std::str::FromStr
|
||||
+ MaybeMallocSizeOf;
|
||||
/// Header hash type
|
||||
type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Ord
|
||||
+ Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]>
|
||||
+ AsMut<[u8]> + MaybeMallocSizeOf;
|
||||
type Hash: Member
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug
|
||||
+ sp_std::hash::Hash
|
||||
+ Ord
|
||||
+ Copy
|
||||
+ MaybeDisplay
|
||||
+ Default
|
||||
+ SimpleBitOps
|
||||
+ Codec
|
||||
+ AsRef<[u8]>
|
||||
+ AsMut<[u8]>
|
||||
+ MaybeMallocSizeOf;
|
||||
/// Hashing algorithm
|
||||
type Hashing: Hash<Output = Self::Hash>;
|
||||
|
||||
@@ -580,14 +677,26 @@ pub trait Header:
|
||||
/// `Extrinsic` pieces of information as well as a `Header`.
|
||||
///
|
||||
/// You can get an iterator over each of the `extrinsics` and retrieve the `header`.
|
||||
pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + MaybeMallocSizeOf + 'static {
|
||||
pub trait Block:
|
||||
Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + MaybeMallocSizeOf + 'static
|
||||
{
|
||||
/// Type for extrinsics.
|
||||
type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize + MaybeMallocSizeOf;
|
||||
/// Header type.
|
||||
type Header: Header<Hash=Self::Hash> + MaybeMallocSizeOf;
|
||||
type Header: Header<Hash = Self::Hash> + MaybeMallocSizeOf;
|
||||
/// Block hash type.
|
||||
type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Ord
|
||||
+ Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>
|
||||
type Hash: Member
|
||||
+ MaybeSerializeDeserialize
|
||||
+ Debug
|
||||
+ sp_std::hash::Hash
|
||||
+ Ord
|
||||
+ Copy
|
||||
+ MaybeDisplay
|
||||
+ Default
|
||||
+ SimpleBitOps
|
||||
+ Codec
|
||||
+ AsRef<[u8]>
|
||||
+ AsMut<[u8]>
|
||||
+ MaybeMallocSizeOf;
|
||||
|
||||
/// Returns a reference to the header.
|
||||
@@ -607,7 +716,6 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + May
|
||||
fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec<u8>;
|
||||
}
|
||||
|
||||
|
||||
/// Something that acts like an `Extrinsic`.
|
||||
pub trait Extrinsic: Sized + MaybeMallocSizeOf {
|
||||
/// The function call.
|
||||
@@ -622,7 +730,9 @@ pub trait Extrinsic: Sized + MaybeMallocSizeOf {
|
||||
|
||||
/// Is this `Extrinsic` signed?
|
||||
/// If no information are available about signed/unsigned, `None` should be returned.
|
||||
fn is_signed(&self) -> Option<bool> { None }
|
||||
fn is_signed(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Create new instance of the extrinsic.
|
||||
///
|
||||
@@ -630,7 +740,9 @@ pub trait Extrinsic: Sized + MaybeMallocSizeOf {
|
||||
/// 1. Inherents (no signature; created by validators during block production)
|
||||
/// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of calls)
|
||||
/// 3. Signed Transactions (with signature; a regular transactions with known origin)
|
||||
fn new(_call: Self::Call, _signed_data: Option<Self::SignaturePayload>) -> Option<Self> { None }
|
||||
fn new(_call: Self::Call, _signed_data: Option<Self::SignaturePayload>) -> Option<Self> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementor is an [`Extrinsic`] and provides metadata about this extrinsic.
|
||||
@@ -878,9 +990,13 @@ impl<AccountId, Call: Dispatchable> SignedExtension for Tuple {
|
||||
Ok(valid)
|
||||
}
|
||||
|
||||
fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: &DispatchInfoOf<Self::Call>, len: usize)
|
||||
-> Result<Self::Pre, TransactionValidityError>
|
||||
{
|
||||
fn pre_dispatch(
|
||||
self,
|
||||
who: &Self::AccountId,
|
||||
call: &Self::Call,
|
||||
info: &DispatchInfoOf<Self::Call>,
|
||||
len: usize,
|
||||
) -> Result<Self::Pre, TransactionValidityError> {
|
||||
Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) ))
|
||||
}
|
||||
|
||||
@@ -928,7 +1044,9 @@ impl SignedExtension for () {
|
||||
type Call = ();
|
||||
type Pre = ();
|
||||
const IDENTIFIER: &'static str = "UnitSignedExtension";
|
||||
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
|
||||
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// An "executable" piece of information, used by the standard Substrate Executive in order to
|
||||
@@ -942,7 +1060,7 @@ pub trait Applyable: Sized + Send + Sync {
|
||||
type Call: Dispatchable;
|
||||
|
||||
/// Checks to see if this is a valid *transaction*. It returns information on it if so.
|
||||
fn validate<V: ValidateUnsigned<Call=Self::Call>>(
|
||||
fn validate<V: ValidateUnsigned<Call = Self::Call>>(
|
||||
&self,
|
||||
source: TransactionSource,
|
||||
info: &DispatchInfoOf<Self::Call>,
|
||||
@@ -951,7 +1069,7 @@ pub trait Applyable: Sized + Send + Sync {
|
||||
|
||||
/// Executes all necessary logic needed prior to dispatch and deconstructs into function call,
|
||||
/// index and sender.
|
||||
fn apply<V: ValidateUnsigned<Call=Self::Call>>(
|
||||
fn apply<V: ValidateUnsigned<Call = Self::Call>>(
|
||||
self,
|
||||
info: &DispatchInfoOf<Self::Call>,
|
||||
len: usize,
|
||||
@@ -1020,7 +1138,9 @@ pub trait OpaqueKeys: Clone {
|
||||
T::decode(&mut self.get_raw(i)).ok()
|
||||
}
|
||||
/// Verify a proof of ownership for the keys.
|
||||
fn ownership_proof_is_valid(&self, _proof: &[u8]) -> bool { true }
|
||||
fn ownership_proof_is_valid(&self, _proof: &[u8]) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Input that adds infinite number of zero after wrapped input.
|
||||
@@ -1056,7 +1176,7 @@ impl<'a, T: codec::Input> codec::Input for AppendZerosInput<'a, T> {
|
||||
into[i] = b;
|
||||
i += 1;
|
||||
} else {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
i
|
||||
@@ -1099,7 +1219,9 @@ impl<'a> codec::Input for TrailingZeroInput<'a> {
|
||||
/// This type can be converted into and possibly from an AccountId (which itself is generic).
|
||||
pub trait AccountIdConversion<AccountId>: Sized {
|
||||
/// Convert into an account ID. This is infallible.
|
||||
fn into_account(&self) -> AccountId { self.into_sub_account(&()) }
|
||||
fn into_account(&self) -> AccountId {
|
||||
self.into_sub_account(&())
|
||||
}
|
||||
|
||||
/// Try to convert an account ID into this type. Might not succeed.
|
||||
fn try_from_account(a: &AccountId) -> Option<Self> {
|
||||
@@ -1125,14 +1247,16 @@ pub trait AccountIdConversion<AccountId>: Sized {
|
||||
/// fill AccountId.
|
||||
impl<T: Encode + Decode + Default, Id: Encode + Decode + TypeId> AccountIdConversion<T> for Id {
|
||||
fn into_sub_account<S: Encode>(&self, sub: S) -> T {
|
||||
(Id::TYPE_ID, self, sub).using_encoded(|b|
|
||||
T::decode(&mut TrailingZeroInput(b))
|
||||
).unwrap_or_default()
|
||||
(Id::TYPE_ID, self, sub)
|
||||
.using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn try_from_sub_account<S: Decode>(x: &T) -> Option<(Self, S)> {
|
||||
x.using_encoded(|d| {
|
||||
if &d[0..4] != Id::TYPE_ID { return None }
|
||||
if &d[0..4] != Id::TYPE_ID {
|
||||
return None
|
||||
}
|
||||
let mut cursor = &d[4..];
|
||||
let result = Decode::decode(&mut cursor).ok()?;
|
||||
if cursor.iter().all(|x| *x == 0) {
|
||||
@@ -1466,19 +1590,19 @@ pub trait BlockNumberProvider {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::codec::{Encode, Decode, Input};
|
||||
use crate::codec::{Decode, Encode, Input};
|
||||
use sp_core::{crypto::Pair, ecdsa};
|
||||
|
||||
mod t {
|
||||
use sp_core::crypto::KeyTypeId;
|
||||
use sp_application_crypto::{app_crypto, sr25519};
|
||||
use sp_core::crypto::KeyTypeId;
|
||||
app_crypto!(sr25519, KeyTypeId(*b"test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_verify_works() {
|
||||
use t::*;
|
||||
use super::AppVerify;
|
||||
use t::*;
|
||||
|
||||
let s = Signature::default();
|
||||
let _ = s.verify(&[0u8; 100][..], &Public::default());
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
//! Transaction validity interface.
|
||||
|
||||
use crate::{
|
||||
codec::{Decode, Encode},
|
||||
RuntimeDebug,
|
||||
};
|
||||
use sp_std::prelude::*;
|
||||
use crate::codec::{Encode, Decode};
|
||||
use crate::RuntimeDebug;
|
||||
|
||||
/// Priority for a transaction. Additive. Higher is better.
|
||||
pub type TransactionPriority = u64;
|
||||
@@ -98,8 +100,7 @@ impl From<InvalidTransaction> for &'static str {
|
||||
InvalidTransaction::Stale => "Transaction is outdated",
|
||||
InvalidTransaction::BadProof => "Transaction has a bad signature",
|
||||
InvalidTransaction::AncientBirthBlock => "Transaction has an ancient birth block",
|
||||
InvalidTransaction::ExhaustsResources =>
|
||||
"Transaction would exhaust the block limits",
|
||||
InvalidTransaction::ExhaustsResources => "Transaction would exhaust the block limits",
|
||||
InvalidTransaction::Payment =>
|
||||
"Inability to pay some fees (e.g. account balance too low)",
|
||||
InvalidTransaction::BadMandatory =>
|
||||
@@ -220,7 +221,9 @@ impl From<UnknownTransaction> for TransactionValidity {
|
||||
/// Depending on the source we might apply different validation schemes.
|
||||
/// For instance we can disallow specific kinds of transactions if they were not produced
|
||||
/// by our local node (for instance off-chain workers).
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, parity_util_mem::MallocSizeOf)]
|
||||
#[derive(
|
||||
Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, parity_util_mem::MallocSizeOf,
|
||||
)]
|
||||
pub enum TransactionSource {
|
||||
/// Transaction is already included in block.
|
||||
///
|
||||
@@ -295,10 +298,7 @@ impl ValidTransaction {
|
||||
/// To avoid conflicts between different parts in runtime it's recommended to build `requires`
|
||||
/// and `provides` tags with a unique prefix.
|
||||
pub fn with_tag_prefix(prefix: &'static str) -> ValidTransactionBuilder {
|
||||
ValidTransactionBuilder {
|
||||
prefix: Some(prefix),
|
||||
validity: Default::default(),
|
||||
}
|
||||
ValidTransactionBuilder { prefix: Some(prefix), validity: Default::default() }
|
||||
}
|
||||
|
||||
/// Combine two instances into one, as a best effort. This will take the superset of each of the
|
||||
@@ -307,8 +307,14 @@ impl ValidTransaction {
|
||||
pub fn combine_with(mut self, mut other: ValidTransaction) -> Self {
|
||||
Self {
|
||||
priority: self.priority.saturating_add(other.priority),
|
||||
requires: { self.requires.append(&mut other.requires); self.requires },
|
||||
provides: { self.provides.append(&mut other.provides); self.provides },
|
||||
requires: {
|
||||
self.requires.append(&mut other.requires);
|
||||
self.requires
|
||||
},
|
||||
provides: {
|
||||
self.provides.append(&mut other.provides);
|
||||
self.provides
|
||||
},
|
||||
longevity: self.longevity.min(other.longevity),
|
||||
propagate: self.propagate && other.propagate,
|
||||
}
|
||||
@@ -412,7 +418,6 @@ impl From<ValidTransactionBuilder> for ValidTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -430,7 +435,10 @@ mod tests {
|
||||
let encoded = v.encode();
|
||||
assert_eq!(
|
||||
encoded,
|
||||
vec![0, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
vec![
|
||||
0, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
]
|
||||
);
|
||||
|
||||
// decode back
|
||||
@@ -450,12 +458,15 @@ mod tests {
|
||||
.priority(3)
|
||||
.priority(6)
|
||||
.into();
|
||||
assert_eq!(a, ValidTransaction {
|
||||
propagate: false,
|
||||
longevity: 5,
|
||||
priority: 6,
|
||||
requires: vec![(PREFIX, 1).encode(), (PREFIX, 2).encode()],
|
||||
provides: vec![(PREFIX, 3).encode(), (PREFIX, 4).encode()],
|
||||
});
|
||||
assert_eq!(
|
||||
a,
|
||||
ValidTransaction {
|
||||
propagate: false,
|
||||
longevity: 5,
|
||||
priority: 6,
|
||||
requires: vec![(PREFIX, 1).encode(), (PREFIX, 2).encode()],
|
||||
provides: vec![(PREFIX, 3).encode(), (PREFIX, 4).encode()],
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user