Remove unneeded Serde requirements (#1076)

* Remove superfluous serde requirements.

* Try to ensure hash is serde

* Fixups

* Building again

* Attempt to reenable Block (doesn't build)

* Fixes compilation for node cli

* Fixes test compilation

* Fix wasm

* Fix tests

* Remove unneeded changes

* Fix up comments

* Reenable some code

* Compile error when origin misused.

* Remove unnecessary includes of `serde_derive`

* Cleanups
This commit is contained in:
Gav Wood
2018-11-12 18:40:18 +01:00
committed by GitHub
parent b76ba06472
commit 57b2896332
62 changed files with 253 additions and 343 deletions
@@ -19,9 +19,13 @@
#[cfg(feature = "std")]
use std::fmt;
#[cfg(feature = "std")]
use serde::{Deserialize, Deserializer};
#[cfg(feature = "std")]
use codec::Decode;
use rstd::prelude::*;
use codec::Codec;
use traits::{self, Member, Block as BlockT, Header as HeaderT};
use traits::{self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize};
use ::Justification;
/// Something to identify a block.
@@ -59,17 +63,28 @@ impl<Block: BlockT> fmt::Display for BlockId<Block> {
/// Abstraction over a substrate block.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Block<Header, Extrinsic> {
pub struct Block<Header, Extrinsic: MaybeSerialize> {
/// The block header.
pub header: Header,
/// The accompanying extrinsics.
pub extrinsics: Vec<Extrinsic>,
}
impl<Header, Extrinsic> traits::Block for Block<Header, Extrinsic>
// TODO: Remove Deserialize for Block once RPC no longer needs it #1098
#[cfg(feature = "std")]
impl<'a, Header: 'a, Extrinsic: 'a + MaybeSerialize> Deserialize<'a> for Block<Header, Extrinsic> where
Block<Header, Extrinsic>: Decode,
{
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
let r = <Vec<u8>>::deserialize(de)?;
Decode::decode(&mut &r[..]).ok_or(::serde::de::Error::custom("Invalid value passed into decode"))
}
}
impl<Header, Extrinsic: MaybeSerialize> traits::Block for Block<Header, Extrinsic>
where
Header: HeaderT,
Extrinsic: Member + Codec + traits::Extrinsic,
@@ -94,12 +109,25 @@ where
/// Abstraction over a substrate block and justification.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct SignedBlock<H, E> {
pub struct SignedBlock<Block> {
/// Full block.
pub block: Block<H, E>,
pub block: Block,
/// Block justification.
pub justification: Justification,
}
// TODO: Remove Deserialize for SignedBlock once RPC no longer needs it #1098
#[cfg(feature = "std")]
impl<'a, Block: BlockT,> Deserialize<'a> for SignedBlock<Block> where
Block::Header: 'a,
Block::Extrinsic: 'a + Codec + MaybeSerialize,
SignedBlock<Block>: Decode,
{
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
let r = <Vec<u8>>::deserialize(de)?;
Decode::decode(&mut &r[..]).ok_or(::serde::de::Error::custom("Invalid value passed into decode"))
}
}
@@ -23,7 +23,7 @@ use traits::{self, Member, SimpleArithmetic, MaybeDisplay};
/// existence implies that it has been checked and is good, particularly with
/// regards to the signature.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct CheckedExtrinsic<AccountId, Index, Call> {
/// Who this purports to be from and the number of extrinsics have come before
/// from the same signer, if anyone (note this is not a signature).
@@ -37,7 +37,7 @@ impl<AccountId, Index, Call> traits::Applyable
where
AccountId: Member + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member
Call: Member,
{
type Index = Index;
type AccountId = AccountId;
@@ -19,7 +19,7 @@
use rstd::prelude::*;
use codec::{Decode, Encode, Codec, Input};
use traits::{self, Member, DigestItem as DigestItemT};
use traits::{self, Member, DigestItem as DigestItemT, MaybeSerializeDebug};
use substrate_primitives::hash::H512 as Signature;
@@ -122,7 +122,10 @@ impl<Hash, AuthorityId> DigestItem<Hash, AuthorityId> {
}
}
impl<Hash: Codec + Member, AuthorityId: Codec + Member> traits::DigestItem for DigestItem<Hash, AuthorityId> {
impl<
Hash: Codec + Member + MaybeSerializeDebug,
AuthorityId: Codec + Member + MaybeSerializeDebug
> traits::DigestItem for DigestItem<Hash, AuthorityId> {
type Hash = Hash;
type AuthorityId = AuthorityId;
@@ -21,7 +21,7 @@ use serde::{Deserialize, Deserializer};
use codec::{Decode, Encode, Codec, Input, Output, HasCompact};
use traits::{self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay,
Hash as HashT, DigestItem as DigestItemT};
Hash as HashT, DigestItem as DigestItemT, MaybeSerializeDebug, MaybeSerializeDebugButNotDeserialize};
use generic::Digest;
/// Abstraction over a block header for a substrate chain.
@@ -42,42 +42,14 @@ pub struct Header<Number, Hash: HashT, DigestItem> {
pub digest: Digest<DigestItem>,
}
// Hack to work around the fact that deriving deserialize doesn't work nicely with
// the `hashing` trait used as a parameter.
// dummy struct that uses the hash type directly.
// https://github.com/serde-rs/serde/issues/1296
#[cfg(feature = "std")]
#[serde(rename_all = "camelCase")]
#[derive(Deserialize)]
struct DeserializeHeader<N, H, D> {
parent_hash: H,
number: N,
state_root: H,
extrinsics_root: H,
digest: Digest<D>,
}
#[cfg(feature = "std")]
impl<N, D, Hash: HashT> From<DeserializeHeader<N, Hash::Output, D>> for Header<N, Hash, D> {
fn from(other: DeserializeHeader<N, Hash::Output, D>) -> Self {
Header {
parent_hash: other.parent_hash,
number: other.number,
state_root: other.state_root,
extrinsics_root: other.extrinsics_root,
digest: other.digest,
}
}
}
// TODO: Remove Deserialize for Header once RPC no longer needs it #1098
#[cfg(feature = "std")]
impl<'a, Number: 'a, Hash: 'a + HashT, DigestItem: 'a> Deserialize<'a> for Header<Number, Hash, DigestItem> where
Number: Deserialize<'a>,
Hash::Output: Deserialize<'a>,
DigestItem: Deserialize<'a>,
Header<Number, Hash, DigestItem>: Decode,
{
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
DeserializeHeader::<Number, Hash::Output, DigestItem>::deserialize(de).map(Into::into)
let r = <Vec<u8>>::deserialize(de)?;
Decode::decode(&mut &r[..]).ok_or(::serde::de::Error::custom("Invalid value passed into decode"))
}
}
@@ -114,11 +86,11 @@ impl<Number, Hash, DigestItem> Encode for Header<Number, Hash, DigestItem> where
}
impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestItem> where
Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec,
Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec,
Hash: HashT,
DigestItem: DigestItemT<Hash = Hash::Output> + Codec,
Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
{
Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeSerializeDebugButNotDeserialize + MaybeDisplay + SimpleBitOps + Codec,
{
type Number = Number;
type Hash = <Hash as HashT>::Output;
type Hashing = Hash;
@@ -17,56 +17,8 @@
//! Tests for the generic implementations of Extrinsic/Header/Block.
use codec::{Decode, Encode};
use substrate_primitives::{H256, H512};
use super::{Digest, Header, DigestItem, UncheckedExtrinsic};
type Block = super::Block<
Header<u64, ::traits::BlakeTwo256, DigestItem<H256, u32>>,
UncheckedExtrinsic<H256, u64, u64, ::Ed25519Signature>,
>;
#[test]
fn block_roundtrip_serialization() {
let block: Block = Block {
header: Header {
parent_hash: [0u8; 32].into(),
number: 100_000,
state_root: [1u8; 32].into(),
extrinsics_root: [2u8; 32].into(),
digest: Digest { logs: vec![
DigestItem::Other::<H256, u32>(vec![1, 2, 3]),
DigestItem::Other::<H256, u32>(vec![4, 5, 6]),
] },
},
extrinsics: vec![
UncheckedExtrinsic::new_signed(
0,
100,
[255u8; 32].into(),
H512::from([0u8; 64]).into()
),
UncheckedExtrinsic::new_signed(
100,
99,
[128u8; 32].into(),
H512::from([255u8; 64]).into()
)
]
};
{
let encoded = ::serde_json::to_vec(&block).unwrap();
let decoded: Block = ::serde_json::from_slice(&encoded).unwrap();
assert_eq!(block, decoded);
}
{
let encoded = block.encode();
let decoded = Block::decode(&mut &encoded[..]).unwrap();
assert_eq!(block, decoded);
}
}
use substrate_primitives::H256;
use super::DigestItem;
#[test]
fn system_digest_item_encoding() {
@@ -25,7 +25,6 @@ use traits::{self, Member, SimpleArithmetic, MaybeDisplay, Lookup};
use super::CheckedExtrinsic;
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct SignatureContent<Address, Index, Signature>
where
Address: Codec,
@@ -40,7 +39,6 @@ where
/// A extrinsic right from the external world. This is unchecked and so
/// can contain a signature.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct UncheckedExtrinsic<Address, Index, Call, Signature>
where
Address: Codec,
@@ -143,6 +141,15 @@ impl<Address: Codec, Index: HasCompact + Codec, Signature: Codec, Call: Encode>
}
}
#[cfg(feature = "std")]
impl<Address: Codec, Index: HasCompact + Codec, Signature: Codec, Call: Encode> serde::Serialize
for UncheckedExtrinsic<Address, Index, Call, Signature>
{
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
}
}
/// TODO: use derive when possible.
#[cfg(feature = "std")]
impl<Address, Index, Signature, Call> fmt::Debug
@@ -30,7 +30,6 @@ const TRANSACTION_VERSION: u8 = 1;
/// A extrinsic right from the external world. This is unchecked and so
/// can contain a signature.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct UncheckedMortalExtrinsic<Address, Index, Call, Signature> {
/// The signature, address, number of extrinsics have come before from
/// the same signer and an era describing the longevity of this transaction,
@@ -58,7 +57,7 @@ impl<Address, Index, Call, Signature> UncheckedMortalExtrinsic<Address, Index, C
}
}
impl<Address, Index, Call, Signature> Extrinsic for UncheckedMortalExtrinsic<Address, Index, Call, Signature> {
impl<Address: Encode, Index: Encode, Call: Encode, Signature: Encode> Extrinsic for UncheckedMortalExtrinsic<Address, Index, Call, Signature> {
fn is_signed(&self) -> Option<bool> {
Some(self.signature.is_some())
}
@@ -158,6 +157,15 @@ where
}
}
#[cfg(feature = "std")]
impl<Address: Encode, Index: Encode, Signature: Encode, Call: Encode> serde::Serialize
for UncheckedMortalExtrinsic<Address, Index, Call, Signature>
{
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
}
}
/// TODO: use derive when possible.
#[cfg(feature = "std")]
impl<Address, Index, Call, Signature> fmt::Debug for UncheckedMortalExtrinsic<Address, Index, Call, Signature> where
+30 -10
View File
@@ -16,9 +16,9 @@
//! Testing utilities.
use serde::{Serialize, de::DeserializeOwned};
use std::{fmt::Debug, ops::Deref};
use codec::Codec;
use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer};
use std::{fmt::Debug, ops::Deref, fmt};
use codec::{Codec, Encode, Decode};
use traits::{self, Checkable, Applyable, BlakeTwo256};
use generic::DigestItem as GenDigestItem;
@@ -101,7 +101,7 @@ impl traits::Header for Header {
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
pub struct ExtrinsicWrapper<Xt>(Xt);
impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt> {
impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt> where Xt: Serialize {
fn is_signed(&self) -> Option<bool> {
None
}
@@ -121,13 +121,13 @@ impl<Xt> Deref for ExtrinsicWrapper<Xt> {
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode)]
pub struct Block<Xt> {
pub header: Header,
pub extrinsics: Vec<Xt>,
}
impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + DeserializeOwned + 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;
type Hash = <Header as traits::Header>::Hash;
@@ -146,20 +146,40 @@ impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + DeserializeOwned +
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, 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[..]).ok_or(DeError::custom("Invalid value passed into decode"))
}
}
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
pub struct TestXt<Call>(pub Option<u64>, pub u64, pub Call);
impl<Call: Codec + Sync + Send + Serialize, Context> Checkable<Context> for TestXt<Call> {
impl<Call> Serialize for TestXt<Call> where TestXt<Call>: Encode
{
fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: Serializer {
self.using_encoded(|bytes| seq.serialize_bytes(bytes))
}
}
impl<Call> Debug for TestXt<Call> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TestXt({:?}, {:?})", self.0, self.1)
}
}
impl<Call: Codec + Sync + Send, Context> Checkable<Context> for TestXt<Call> {
type Checked = Self;
fn check(self, _: &Context) -> Result<Self::Checked, &'static str> { Ok(self) }
}
impl<Call: Codec + Sync + Send + Serialize> traits::Extrinsic for TestXt<Call> {
impl<Call: Codec + Sync + Send> traits::Extrinsic for TestXt<Call> {
fn is_signed(&self) -> Option<bool> {
None
}
}
impl<Call> Applyable for TestXt<Call> where
Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Serialize + DeserializeOwned,
Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug,
{
type AccountId = u64;
type Index = u64;
+39 -20
View File
@@ -246,7 +246,7 @@ tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W,
pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived
// traits must be fulfilled by all type parameters.
/// The hash type produced.
type Output: Member + AsRef<[u8]> + AsMut<[u8]>;
type Output: Member + MaybeSerializeDebug + AsRef<[u8]> + AsMut<[u8]>;
/// Produce the hash of some byte-slice.
fn hash(s: &[u8]) -> Self::Output;
@@ -365,6 +365,16 @@ pub trait MaybeSerializeDebugButNotDeserialize {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSerializeDebugButNotDeserialize for T {}
#[cfg(feature = "std")]
pub trait MaybeSerialize: Serialize {}
#[cfg(feature = "std")]
impl<T: Serialize> MaybeSerialize for T {}
#[cfg(not(feature = "std"))]
pub trait MaybeSerialize {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSerialize for T {}
#[cfg(feature = "std")]
pub trait MaybeSerializeDebug: Serialize + DeserializeOwned + Debug {}
#[cfg(feature = "std")]
@@ -375,6 +385,16 @@ pub trait MaybeSerializeDebug {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSerializeDebug for T {}
#[cfg(feature = "std")]
pub trait MaybeDebug: Debug {}
#[cfg(feature = "std")]
impl<T: Debug> MaybeDebug for T {}
#[cfg(not(feature = "std"))]
pub trait MaybeDebug {}
#[cfg(not(feature = "std"))]
impl<T> MaybeDebug for T {}
#[cfg(feature = "std")]
pub trait MaybeDisplay: Display {}
#[cfg(feature = "std")]
@@ -395,9 +415,8 @@ pub trait MaybeDecode {}
#[cfg(not(feature = "std"))]
impl<T> MaybeDecode for T {}
pub trait Member: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'static {}
impl<T: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'static> Member for T {}
pub trait Member: Send + Sync + Sized + MaybeDebug + Eq + PartialEq + Clone + 'static {}
impl<T: Send + Sync + Sized + MaybeDebug + Eq + PartialEq + Clone + 'static> Member for T {}
/// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`,
/// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and
@@ -405,8 +424,8 @@ impl<T: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'st
///
/// You can also create a `new` one from those fields.
pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'static {
type Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec;
type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec;
type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
type Hashing: Hash<Output = Self::Hash>;
type Digest: Digest<Hash = Self::Hash>;
@@ -445,9 +464,9 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'stat
///
/// You can get an iterator over each of the `extrinsics` and retrieve the `header`.
pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'static {
type Extrinsic: Member + Codec + Extrinsic;
type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize;
type Header: Header<Hash=Self::Hash>;
type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
fn header(&self) -> &Self::Header;
fn extrinsics(&self) -> &[Self::Extrinsic];
@@ -458,6 +477,13 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'stati
}
}
/// Something that acts like an `Extrinsic`.
pub trait Extrinsic {
/// Is this `Extrinsic` signed?
/// If no information are available about signed/unsigned, `None` should be returned.
fn is_signed(&self) -> Option<bool> { None }
}
/// Extract the hashing type for a block.
pub type HashFor<B> = <<B as Block>::Header as Header>::Hashing;
/// Extract the number type for a block.
@@ -516,8 +542,8 @@ pub trait Applyable: Sized + Send + Sync {
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
/// each `Codec`.
pub trait Digest: Member + Default {
type Hash: Member;
pub trait Digest: Member + MaybeSerializeDebug + Default {
type Hash: Member + MaybeSerializeDebug;
type Item: DigestItem<Hash = Self::Hash>;
/// Get reference to all digest items.
@@ -539,9 +565,9 @@ pub trait Digest: Member + Default {
/// for casting member to 'system' log items, known to substrate.
///
/// If the runtime does not supports some 'system' items, use `()` as a stub.
pub trait DigestItem: Codec + Member {
type Hash: Member;
type AuthorityId: Member;
pub trait DigestItem: Codec + Member + MaybeSerializeDebug {
type Hash: Member + MaybeSerializeDebug;
type AuthorityId: Member + MaybeSerializeDebug;
/// Returns Some if the entry is the `AuthoritiesChange` entry.
fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]>;
@@ -571,10 +597,3 @@ pub trait ProvideInherent {
block: &Block, data: Self::Inherent, extract_function: &F
) -> Result<(), Self::Error>;
}
/// Something that acts like an `Extrinsic`.
pub trait Extrinsic {
/// Is this `Extrinsic` signed?
/// If no information are available about signed/unsigned, `None` should be returned.
fn is_signed(&self) -> Option<bool> { None }
}