// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
//! Testing utilities.
use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer};
use std::{fmt::Debug, ops::Deref, fmt, cell::RefCell};
use crate::codec::{Codec, Encode, Decode};
use crate::traits::{
self, Checkable, Applyable, BlakeTwo256, OpaqueKeys,
SignedExtension, Dispatchable,
};
use crate::traits::ValidateUnsigned;
use crate::{generic::{self, CheckSignature}, KeyTypeId, ApplyExtrinsicResult};
pub use sp_core::{H256, sr25519};
use sp_core::{crypto::{CryptoType, Dummy, key_types, Public}, U256};
use crate::transaction_validity::{TransactionValidity, TransactionValidityError, InvalidTransaction};
/// Authority Id
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct UintAuthorityId(pub u64);
impl From for UintAuthorityId {
fn from(id: u64) -> Self {
UintAuthorityId(id)
}
}
impl From for u64 {
fn from(id: UintAuthorityId) -> u64 {
id.0
}
}
impl UintAuthorityId {
/// Convert this authority id into a public key.
pub fn to_public_key(&self) -> T {
let bytes: [u8; 32] = U256::from(self.0).into();
T::from_slice(&bytes)
}
}
impl CryptoType for UintAuthorityId {
type Pair = Dummy;
}
impl AsRef<[u8]> for UintAuthorityId {
fn as_ref(&self) -> &[u8] {
// 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::())
}
}
}
thread_local! {
/// A list of all UintAuthorityId keys returned to the runtime.
static ALL_KEYS: RefCell> = RefCell::new(vec![]);
}
impl UintAuthorityId {
/// Set the list of keys returned by the runtime call for all keys of that type.
pub fn set_all_keys>(keys: impl IntoIterator- ) {
ALL_KEYS.with(|l| *l.borrow_mut() = keys.into_iter().map(Into::into).collect())
}
}
impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId {
const ID: KeyTypeId = key_types::DUMMY;
type Signature = u64;
fn all() -> Vec {
ALL_KEYS.with(|l| l.borrow().clone())
}
fn generate_pair(_: Option>) -> Self {
use rand::RngCore;
UintAuthorityId(rand::thread_rng().next_u64())
}
fn sign>(&self, msg: &M) -> Option {
let mut signature = [0u8; 8];
msg.as_ref().iter()
.chain(std::iter::repeat(&42u8))
.take(8)
.enumerate()
.for_each(|(i, v)| { signature[i] = *v; });
Some(u64::from_le_bytes(signature))
}
fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool {
let mut msg_signature = [0u8; 8];
msg.as_ref().iter()
.chain(std::iter::repeat(&42))
.take(8)
.enumerate()
.for_each(|(i, v)| { msg_signature[i] = *v; });
u64::from_le_bytes(msg_signature) == *signature
}
fn to_raw_vec(&self) -> Vec {
AsRef::<[u8]>::as_ref(self).to_vec()
}
}
impl OpaqueKeys for UintAuthorityId {
type KeyTypeIdProviders = ();
fn key_ids() -> &'static [KeyTypeId] {
&[key_types::DUMMY]
}
fn get_raw(&self, _: KeyTypeId) -> &[u8] {
self.as_ref()
}
fn get(&self, _: KeyTypeId) -> Option {
self.using_encoded(|mut x| T::decode(&mut x)).ok()
}
}
impl crate::BoundToRuntimeAppPublic for UintAuthorityId {
type Public = Self;
}
/// Digest item
pub type DigestItem = generic::DigestItem;
/// Header Digest
pub type Digest = generic::Digest;
/// Block Header
#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, Default, parity_util_mem::MallocSizeOf)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Header {
/// Parent hash
pub parent_hash: H256,
/// Block Number
pub number: u64,
/// Post-execution state trie root
pub state_root: H256,
/// Merkle root of block's extrinsics
pub extrinsics_root: H256,
/// Digest items
pub digest: Digest,
}
impl traits::Header for Header {
type Number = u64;
type Hashing = BlakeTwo256;
type Hash = H256;
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 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 digest(&self) -> &Digest { &self.digest }
fn digest_mut(&mut self) -> &mut Digest { &mut self.digest }
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Digest,
) -> Self {
Header {
number,
extrinsics_root,
state_root,
parent_hash,
digest,
}
}
}
impl Header {
/// A new header with the given number and default hash for all other fields.
pub fn new_from_number(number: ::Number) -> Self {
Self {
number,
..Default::default()
}
}
}
impl<'a> Deserialize<'a> for Header {
fn deserialize>(de: D) -> Result {
let r = >::deserialize(de)?;
Decode::decode(&mut &r[..])
.map_err(|e| DeError::custom(format!("Invalid value passed into decode: {}", e.what())))
}
}
/// An opaque extrinsic wrapper type.
#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode, parity_util_mem::MallocSizeOf)]
pub struct ExtrinsicWrapper(Xt);
impl traits::Extrinsic for ExtrinsicWrapper
where Xt: parity_util_mem::MallocSizeOf
{
type Call = ();
type SignaturePayload = ();
fn is_signed(&self) -> Option {
None
}
}
impl serde::Serialize for ExtrinsicWrapper {
fn serialize
(&self, seq: S) -> Result where S: ::serde::Serializer {
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
}
}
impl From for ExtrinsicWrapper {
fn from(xt: Xt) -> Self {
ExtrinsicWrapper(xt)
}
}
impl Deref for ExtrinsicWrapper {
type Target = Xt;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// Testing block
#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, parity_util_mem::MallocSizeOf)]
pub struct Block {
/// Block header
pub header: Header,
/// List of extrinsics
pub extrinsics: Vec,
}
impl traits::Block
for Block
{
type Extrinsic = Xt;
type Header = Header;
type Hash = ::Hash;
fn header(&self) -> &Self::Header {
&self.header
}
fn extrinsics(&self) -> &[Self::Extrinsic] {
&self.extrinsics[..]
}
fn deconstruct(self) -> (Self::Header, Vec) {
(self.header, self.extrinsics)
}
fn new(header: Self::Header, extrinsics: Vec) -> Self {
Block { header, extrinsics }
}
fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec {
(header, extrinsics).encode()
}
}
impl<'a, Xt> Deserialize<'a> for Block where Block: Decode {
fn deserialize>(de: D) -> Result {
let r = >::deserialize(de)?;
Decode::decode(&mut &r[..])
.map_err(|e| DeError::custom(format!("Invalid value passed into decode: {}", e.what())))
}
}
/// Test validity.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
pub enum TestValidity {
/// Valid variant that will pass all checks.
Valid,
/// Variant with invalid signature.
///
/// Will fail signature check.
SignatureInvalid(TransactionValidityError),
/// Variant with invalid logic.
///
/// Will fail all checks.
OtherInvalid(TransactionValidityError),
}
/// Test transaction.
///
/// Used to mock actual transaction.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
pub struct TestXt {
/// Signature with extra.
///
/// if some, then the transaction is signed. Transaction is unsigned otherwise.
pub signature: Option<(u64, Extra)>,
/// Validity.
///
/// Instantiate invalid variant and transaction will fail correpsonding checks.
pub validity: TestValidity,
/// Call.
pub call: Call,
}
impl TestXt {
/// New signed test `TextXt`.
pub fn new_signed(signature: (u64, Extra), call: Call) -> Self {
TestXt {
signature: Some(signature),
validity: TestValidity::Valid,
call,
}
}
/// New unsigned test `TextXt`.
pub fn new_unsigned(call: Call) -> Self {
TestXt {
signature: None,
validity: TestValidity::Valid,
call,
}
}
/// Build invalid variant of `TestXt`.
pub fn invalid(mut self, err: TransactionValidityError) -> Self {
self.validity = TestValidity::OtherInvalid(err);
self
}
/// Build badly signed variant of `TestXt`.
pub fn badly_signed(mut self) -> Self {
self.validity = TestValidity::SignatureInvalid(TransactionValidityError::Invalid(InvalidTransaction::BadProof));
self
}
}
// Non-opaque extrinsics always 0.
parity_util_mem::malloc_size_of_is_0!(any: TestXt);
impl Serialize for TestXt where TestXt: Encode {
fn serialize(&self, seq: S) -> Result where S: Serializer {
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
}
}
impl Debug for TestXt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TestXt({:?}, {}, ...)",
self.signature.as_ref().map(|x| &x.0),
if let TestValidity::Valid = self.validity { "valid" } else { "invalid" }
)
}
}
impl Checkable for TestXt {
type Checked = Self;
fn check(self, signature: CheckSignature, _: &Context) -> Result {
match self.validity {
TestValidity::Valid => Ok(self),
TestValidity::SignatureInvalid(e) =>
if let CheckSignature::No = signature {
Ok(self)
} else {
Err(e)
},
TestValidity::OtherInvalid(e) => Err(e),
}
}
}
impl traits::Extrinsic for TestXt {
type Call = Call;
type SignaturePayload = (u64, Extra);
fn is_signed(&self) -> Option {
Some(self.signature.is_some())
}
fn new(call: Call, signature: Option) -> Option {
Some(TestXt { signature, call, validity: TestValidity::Valid })
}
}
impl Applyable for TestXt where
Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Dispatchable,
Extra: SignedExtension,
Origin: From