diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index 6df1104377..0ad4317dd9 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -3852,6 +3852,7 @@ dependencies = [
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
+ "substrate-debug-derive 2.0.0",
]
[[package]]
@@ -3860,6 +3861,7 @@ version = "2.0.0"
dependencies = [
"hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
@@ -4102,6 +4104,7 @@ version = "2.0.0"
dependencies = [
"parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-primitives 2.0.0",
"sr-std 2.0.0",
"substrate-client 2.0.0",
]
@@ -4416,6 +4419,7 @@ version = "2.0.0"
dependencies = [
"bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"impl-trait-for-tuples 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -5088,6 +5092,15 @@ dependencies = [
"substrate-primitives 2.0.0",
]
+[[package]]
+name = "substrate-debug-derive"
+version = "2.0.0"
+dependencies = [
+ "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "substrate-executor"
version = "2.0.0"
@@ -5367,6 +5380,7 @@ dependencies = [
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
"substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "substrate-debug-derive 2.0.0",
"substrate-externalities 2.0.0",
"substrate-primitives-storage 2.0.0",
"substrate-serializer 2.0.0",
@@ -5383,6 +5397,7 @@ dependencies = [
"impl-serde 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
+ "substrate-debug-derive 2.0.0",
]
[[package]]
diff --git a/substrate/core/application-crypto/src/lib.rs b/substrate/core/application-crypto/src/lib.rs
index e3366a461a..16eda53238 100644
--- a/substrate/core/application-crypto/src/lib.rs
+++ b/substrate/core/application-crypto/src/lib.rs
@@ -21,7 +21,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[doc(hidden)]
-pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}};
+pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug};
#[doc(hidden)]
#[cfg(feature = "std")]
pub use primitives::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair};
@@ -139,10 +139,12 @@ macro_rules! app_crypto {
$crate::wrap!{
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
#[derive(
- Clone, Default, Eq, PartialEq, Ord, PartialOrd, $crate::codec::Encode,
+ Clone, Default, Eq, PartialEq, Ord, PartialOrd,
+ $crate::codec::Encode,
$crate::codec::Decode,
+ $crate::RuntimeDebug,
)]
- #[cfg_attr(feature = "std", derive(Debug, Hash))]
+ #[cfg_attr(feature = "std", derive(Hash))]
pub struct Public($public);
}
@@ -239,8 +241,12 @@ macro_rules! app_crypto {
$crate::wrap! {
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
- #[derive(Clone, Default, Eq, PartialEq, $crate::codec::Encode, $crate::codec::Decode)]
- #[cfg_attr(feature = "std", derive(Debug, Hash))]
+ #[derive(Clone, Default, Eq, PartialEq,
+ $crate::codec::Encode,
+ $crate::codec::Decode,
+ $crate::RuntimeDebug,
+ )]
+ #[cfg_attr(feature = "std", derive(Hash))]
pub struct Signature($sig);
}
diff --git a/substrate/core/application-crypto/src/traits.rs b/substrate/core/application-crypto/src/traits.rs
index aad076bd90..49d3a44aee 100644
--- a/substrate/core/application-crypto/src/traits.rs
+++ b/substrate/core/application-crypto/src/traits.rs
@@ -14,10 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
-use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public};
#[cfg(feature = "std")]
use primitives::crypto::Pair;
+
use codec::Codec;
+use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public};
+use rstd::fmt::Debug;
/// An application-specific key.
pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone {
@@ -38,23 +40,25 @@ pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone {
const ID: KeyTypeId;
}
-/// Type which implements Debug and Hash in std, not when no-std (std variant).
+/// Type which implements Hash in std, not when no-std (std variant).
#[cfg(feature = "std")]
-pub trait MaybeDebugHash: std::fmt::Debug + std::hash::Hash {}
+pub trait MaybeHash: std::hash::Hash {}
#[cfg(feature = "std")]
-impl MaybeDebugHash for T {}
+impl MaybeHash for T {}
-/// Type which implements Debug and Hash in std, not when no-std (no-std variant).
+/// Type which implements Hash in std, not when no-std (no-std variant).
#[cfg(not(feature = "std"))]
-pub trait MaybeDebugHash {}
+pub trait MaybeHash {}
#[cfg(not(feature = "std"))]
-impl MaybeDebugHash for T {}
+impl MaybeHash for T {}
/// A application's public key.
-pub trait AppPublic: AppKey + Public + Ord + PartialOrd + Eq + PartialEq + MaybeDebugHash + codec::Codec {
+pub trait AppPublic:
+ AppKey + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec
+{
/// The wrapped type which is just a plain instance of `Public`.
type Generic:
- IsWrappedBy + Public + Ord + PartialOrd + Eq + PartialEq + MaybeDebugHash + codec::Codec;
+ IsWrappedBy + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec;
}
/// A application's key pair.
@@ -65,15 +69,15 @@ pub trait AppPair: AppKey + Pair::Public> {
}
/// A application's signature.
-pub trait AppSignature: AppKey + Eq + PartialEq + MaybeDebugHash {
+pub trait AppSignature: AppKey + Eq + PartialEq + Debug + MaybeHash {
/// The wrapped type which is just a plain instance of `Signature`.
- type Generic: IsWrappedBy + Eq + PartialEq + MaybeDebugHash;
+ type Generic: IsWrappedBy + Eq + PartialEq + Debug + MaybeHash;
}
/// A runtime interface for a public key.
pub trait RuntimePublic: Sized {
/// The signature that will be generated when signing with the corresponding private key.
- type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone;
+ type Signature: Codec + Debug + MaybeHash + Eq + PartialEq + Clone;
/// Returns all public keys for the given key type in the keystore.
fn all(key_type: KeyTypeId) -> crate::Vec;
@@ -101,7 +105,7 @@ pub trait RuntimeAppPublic: Sized {
const ID: KeyTypeId;
/// The signature that will be generated when signing with the corresponding private key.
- type Signature: Codec + MaybeDebugHash + Eq + PartialEq + Clone;
+ type Signature: Codec + Debug + MaybeHash + Eq + PartialEq + Clone;
/// Returns all public keys for this application in the keystore.
fn all() -> crate::Vec;
diff --git a/substrate/core/authority-discovery/primitives/src/lib.rs b/substrate/core/authority-discovery/primitives/src/lib.rs
index 13da4de020..7c56dc6ca4 100644
--- a/substrate/core/authority-discovery/primitives/src/lib.rs
+++ b/substrate/core/authority-discovery/primitives/src/lib.rs
@@ -20,12 +20,13 @@
use client::decl_runtime_apis;
use rstd::vec::Vec;
+use sr_primitives::RuntimeDebug;
-#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)]
-#[cfg_attr(feature = "std", derive(Debug, Hash))]
+#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Hash))]
pub struct Signature(pub Vec);
-#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone)]
-#[cfg_attr(feature = "std", derive(Debug, Hash))]
+#[derive(codec::Encode, codec::Decode, Eq, PartialEq, Clone, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Hash))]
pub struct AuthorityId(pub Vec);
decl_runtime_apis! {
diff --git a/substrate/core/consensus/babe/primitives/src/digest.rs b/substrate/core/consensus/babe/primitives/src/digest.rs
index ff62ae29c5..95dd247810 100644
--- a/substrate/core/consensus/babe/primitives/src/digest.rs
+++ b/substrate/core/consensus/babe/primitives/src/digest.rs
@@ -195,8 +195,7 @@ impl Decode for BabePreDigest {
/// Information about the next epoch. This is broadcast in the first block
/// of the epoch.
-#[derive(Decode, Encode, Default, PartialEq, Eq, Clone)]
-#[cfg_attr(any(feature = "std", test), derive(Debug))]
+#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)]
pub struct NextEpochDescriptor {
/// The authorities.
pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
diff --git a/substrate/core/consensus/babe/primitives/src/lib.rs b/substrate/core/consensus/babe/primitives/src/lib.rs
index 1293b7c8ba..c464e797d8 100644
--- a/substrate/core/consensus/babe/primitives/src/lib.rs
+++ b/substrate/core/consensus/babe/primitives/src/lib.rs
@@ -23,7 +23,7 @@ mod digest;
use codec::{Encode, Decode};
use rstd::vec::Vec;
-use sr_primitives::ConsensusEngineId;
+use sr_primitives::{ConsensusEngineId, RuntimeDebug};
use substrate_client::decl_runtime_apis;
#[cfg(feature = "std")]
@@ -79,8 +79,7 @@ pub type BabeAuthorityWeight = u64;
pub type BabeBlockWeight = u32;
/// BABE epoch information
-#[derive(Decode, Encode, Default, PartialEq, Eq, Clone)]
-#[cfg_attr(any(feature = "std", test), derive(Debug))]
+#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, RuntimeDebug)]
pub struct Epoch {
/// The epoch index
pub epoch_index: u64,
@@ -127,8 +126,7 @@ pub enum ConsensusLog {
}
/// Configuration data used by the BABE consensus engine.
-#[derive(Clone, PartialEq, Eq, Encode, Decode)]
-#[cfg_attr(any(feature = "std", test), derive(Debug))]
+#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
pub struct BabeConfiguration {
/// The slot duration in milliseconds for BABE. Currently, only
/// the value provided by this type at genesis will be used.
diff --git a/substrate/core/executor/src/host_interface.rs b/substrate/core/executor/src/host_interface.rs
index 7c99415f6c..e6386ff1ac 100644
--- a/substrate/core/executor/src/host_interface.rs
+++ b/substrate/core/executor/src/host_interface.rs
@@ -151,6 +151,22 @@ impl_wasm_host_interface! {
Ok(())
}
+ ext_log(
+ level: u32,
+ target_data: Pointer,
+ target_len: WordSize,
+ message_data: Pointer,
+ message_len: WordSize,
+ ) {
+ let target = context.read_memory(target_data, target_len)
+ .map_err(|_| "Invalid attempt to determine target in ext_log")?;
+ let message = context.read_memory(message_data, message_len)
+ .map_err(|_| "Invalid attempt to determine message in ext_log")?;
+
+ runtime_io::log(level.into(), &target, &message);
+ Ok(())
+ }
+
ext_set_storage(
key_data: Pointer,
key_len: WordSize,
diff --git a/substrate/core/finality-grandpa/primitives/src/lib.rs b/substrate/core/finality-grandpa/primitives/src/lib.rs
index a439953899..27139bbeef 100644
--- a/substrate/core/finality-grandpa/primitives/src/lib.rs
+++ b/substrate/core/finality-grandpa/primitives/src/lib.rs
@@ -24,7 +24,7 @@ extern crate alloc;
#[cfg(feature = "std")]
use serde::Serialize;
use codec::{Encode, Decode, Codec};
-use sr_primitives::ConsensusEngineId;
+use sr_primitives::{ConsensusEngineId, RuntimeDebug};
use client::decl_runtime_apis;
use rstd::vec::Vec;
@@ -59,8 +59,8 @@ pub type SetId = u64;
pub type RoundNumber = u64;
/// A scheduled change of authority set.
-#[cfg_attr(feature = "std", derive(Debug, Serialize))]
-#[derive(Clone, Eq, PartialEq, Encode, Decode)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)]
pub struct ScheduledChange {
/// The new authorities after the change, along with their respective weights.
pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>,
@@ -69,8 +69,8 @@ pub struct ScheduledChange {
}
/// An consensus log item for GRANDPA.
-#[cfg_attr(feature = "std", derive(Serialize, Debug))]
-#[derive(Decode, Encode, PartialEq, Eq, Clone)]
+#[cfg_attr(feature = "std", derive(Serialize))]
+#[derive(Decode, Encode, PartialEq, Eq, Clone, RuntimeDebug)]
pub enum ConsensusLog {
/// Schedule an authority set change.
///
diff --git a/substrate/core/phragmen/src/lib.rs b/substrate/core/phragmen/src/lib.rs
index e15a857b5f..7377bac2f8 100644
--- a/substrate/core/phragmen/src/lib.rs
+++ b/substrate/core/phragmen/src/lib.rs
@@ -34,6 +34,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
use rstd::{prelude::*, collections::btree_map::BTreeMap};
+use sr_primitives::RuntimeDebug;
use sr_primitives::{helpers_128bit::multiply_by_rational, Perbill, Rational128};
use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating, Bounded};
@@ -54,8 +55,7 @@ pub type ExtendedBalance = u128;
const DEN: u128 = u128::max_value();
/// A candidate entity for phragmen election.
-#[derive(Clone, Default)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Default, RuntimeDebug)]
pub struct Candidate {
/// Identifier.
pub who: AccountId,
@@ -68,8 +68,7 @@ pub struct Candidate {
}
/// A voter entity.
-#[derive(Clone, Default)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Default, RuntimeDebug)]
pub struct Voter {
/// Identifier.
who: AccountId,
@@ -82,8 +81,7 @@ pub struct Voter {
}
/// A candidate being backed by a voter.
-#[derive(Clone, Default)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Default, RuntimeDebug)]
pub struct Edge {
/// Identifier.
who: AccountId,
@@ -100,7 +98,7 @@ pub type PhragmenAssignment = (AccountId, Perbill);
pub type PhragmenStakedAssignment = (AccountId, ExtendedBalance);
/// Final result of the phragmen election.
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(RuntimeDebug)]
pub struct PhragmenResult {
/// Just winners zipped with their approval stake. Note that the approval stake is merely the
/// sub of their received stake and could be used for very basic sorting and approval voting.
@@ -117,8 +115,7 @@ pub struct PhragmenResult {
///
/// This, at the current version, resembles the `Exposure` defined in the staking SRML module, yet
/// they do not necessarily have to be the same.
-#[derive(Default)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Default, RuntimeDebug)]
pub struct Support {
/// The amount of support as the effect of self-vote.
pub own: ExtendedBalance,
diff --git a/substrate/core/primitives/Cargo.toml b/substrate/core/primitives/Cargo.toml
index a527f16c1c..557ce55b88 100644
--- a/substrate/core/primitives/Cargo.toml
+++ b/substrate/core/primitives/Cargo.toml
@@ -8,12 +8,12 @@ edition = "2018"
rstd = { package = "sr-std", path = "../sr-std", default-features = false }
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
rustc-hex = { version = "2.0.1", default-features = false }
+log = { version = "0.4.8", default-features = false }
serde = { version = "1.0.101", optional = true, features = ["derive"] }
twox-hash = { version = "1.5.0", optional = true }
byteorder = { version = "1.3.2", default-features = false }
primitive-types = { version = "0.5.1", default-features = false, features = ["codec"] }
impl-serde = { version = "0.2.1", optional = true }
-log = { version = "0.4.8", optional = true }
wasmi = { version = "0.5.1", optional = true }
hash-db = { version = "0.15.2", default-features = false }
hash256-std-hasher = { version = "0.15.2", default-features = false }
@@ -31,6 +31,7 @@ num-traits = { version = "0.2.8", default-features = false }
zeroize = "0.10.1"
lazy_static = { version = "1.4.0", optional = true }
parking_lot = { version = "0.9.0", optional = true }
+substrate-debug-derive = { version = "2.0.0", path = "./debug-derive" }
externalities = { package = "substrate-externalities", path = "../externalities", optional = true }
primitives-storage = { package = "substrate-primitives-storage", path = "storage", default-features = false }
@@ -51,7 +52,7 @@ bench = false
[features]
default = ["std"]
std = [
- "log",
+ "log/std",
"wasmi",
"lazy_static",
"parking_lot",
@@ -81,6 +82,7 @@ std = [
"schnorrkel",
"regex",
"num-traits/std",
+ "substrate-debug-derive/std",
"externalities",
"primitives-storage/std",
]
diff --git a/substrate/core/primitives/debug-derive/Cargo.toml b/substrate/core/primitives/debug-derive/Cargo.toml
new file mode 100644
index 0000000000..9c7b7aa1ba
--- /dev/null
+++ b/substrate/core/primitives/debug-derive/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "substrate-debug-derive"
+version = "2.0.0"
+authors = ["Parity Technologies "]
+edition = "2018"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+quote = "1.0.2"
+syn = "1.0.5"
+proc-macro2 = "1.0"
+
+[features]
+std = []
+
+[dev-dependencies]
+
diff --git a/substrate/core/primitives/debug-derive/src/impls.rs b/substrate/core/primitives/debug-derive/src/impls.rs
new file mode 100644
index 0000000000..decceca044
--- /dev/null
+++ b/substrate/core/primitives/debug-derive/src/impls.rs
@@ -0,0 +1,217 @@
+// Copyright 2019 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 .
+
+use quote::quote;
+use proc_macro2::TokenStream;
+use syn::{Data, DeriveInput, parse_quote};
+
+pub fn debug_derive(ast: DeriveInput) -> proc_macro::TokenStream {
+ let name_str = ast.ident.to_string();
+ let implementation = implementation::derive(&name_str, &ast.data);
+ let name = &ast.ident;
+ let mut generics = ast.generics.clone();
+ let (impl_generics, ty_generics, where_clause) = {
+ let wh = generics.make_where_clause();
+ for t in ast.generics.type_params() {
+ let name = &t.ident;
+ wh.predicates.push(parse_quote!{ #name : core::fmt::Debug });
+ }
+ generics.split_for_impl()
+ };
+ let gen = quote!{
+ impl #impl_generics core::fmt::Debug for #name #ty_generics #where_clause {
+ fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
+ #implementation
+ }
+ }
+ };
+
+ gen.into()
+}
+
+#[cfg(not(feature = "std"))]
+mod implementation {
+ use super::*;
+
+ /// Derive the inner implementation of `Debug::fmt` function.
+ ///
+ /// Non-std environment. We do nothing to prevent bloating the size of runtime.
+ /// Implement `Printable` if you need to print the details.
+ pub fn derive(_name_str: &str, _data: &Data) -> TokenStream {
+ quote! {
+ fmt.write_str("")
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+mod implementation {
+ use super::*;
+ use proc_macro2::Span;
+ use syn::{Ident, Index, token::SelfValue};
+
+ /// Derive the inner implementation of `Debug::fmt` function.
+ pub fn derive(name_str: &str, data: &Data) -> TokenStream {
+ match *data {
+ Data::Struct(ref s) => derive_struct(&name_str, &s.fields),
+ Data::Union(ref u) => derive_fields(&name_str, Fields::new(u.fields.named.iter(), None)),
+ Data::Enum(ref e) => derive_enum(&name_str, &e),
+ }
+ }
+
+ enum Fields {
+ Indexed {
+ indices: Vec,
+ },
+ Unnamed {
+ vars: Vec,
+ },
+ Named {
+ names: Vec,
+ this: Option,
+ },
+ }
+
+ impl Fields {
+ fn new<'a>(fields: impl Iterator- , this: Option) -> Self {
+ let mut indices = vec![];
+ let mut names = vec![];
+
+ for (i, f) in fields.enumerate() {
+ if let Some(ident) = f.ident.clone() {
+ names.push(ident);
+ } else {
+ indices.push(Index::from(i));
+ }
+ }
+
+ if names.is_empty() {
+ Self::Indexed {
+ indices,
+ }
+ } else {
+ Self::Named {
+ names,
+ this,
+ }
+ }
+ }
+ }
+
+ fn derive_fields<'a>(
+ name_str: &str,
+ fields: Fields,
+ ) -> TokenStream {
+ match fields {
+ Fields::Named { names, this } => {
+ let names_str: Vec<_> = names.iter()
+ .map(|x| x.to_string())
+ .collect();
+
+ let fields = match this {
+ None => quote! { #( .field(#names_str, #names) )* },
+ Some(this) => quote! { #( .field(#names_str, this.#names) )* },
+ };
+
+ quote! {
+ fmt.debug_struct(#name_str)
+ #fields
+ .finish()
+ }
+
+ },
+ Fields::Indexed { indices } => {
+ quote! {
+ fmt.debug_tuple(#name_str)
+ #( .field(&self.#indices) )*
+ .finish()
+ }
+ },
+ Fields::Unnamed { vars } => {
+ quote! {
+ fmt.debug_tuple(#name_str)
+ #( .field(#vars) )*
+ .finish()
+ }
+ },
+ }
+ }
+
+ fn derive_enum(
+ name: &str,
+ e: &syn::DataEnum,
+ ) -> TokenStream {
+ let v = e.variants
+ .iter()
+ .map(|v| {
+ let name = format!("{}::{}", name, v.ident);
+ let ident = &v.ident;
+ match v.fields {
+ syn::Fields::Named(ref f) => {
+ let names: Vec<_> = f.named.iter().flat_map(|f| f.ident.clone()).collect();
+ let fields_impl = derive_fields(&name, Fields::Named {
+ names: names.clone(),
+ this: None,
+ });
+ (ident, (quote!{ { #( ref #names ),* } }, fields_impl))
+ },
+ syn::Fields::Unnamed(ref f) => {
+ let names = f.unnamed.iter()
+ .enumerate()
+ .map(|(id, _)| Ident::new(&format!("a{}", id), Span::call_site()))
+ .collect::>();
+ let fields_impl = derive_fields(&name, Fields::Unnamed { vars: names.clone() });
+ (ident, (quote! { ( #( ref #names ),* ) }, fields_impl))
+ },
+ syn::Fields::Unit => {
+ let fields_impl = derive_fields(&name, Fields::Indexed { indices: vec![] });
+ (ident, (quote! { }, fields_impl))
+ },
+ }
+ });
+
+ type Vecs = (Vec, Vec);
+ let (variants, others): Vecs<_, _> = v.unzip();
+ let (match_fields, variants_impl): Vecs<_, _> = others.into_iter().unzip();
+
+ quote! {
+ match self {
+ #( Self::#variants #match_fields => #variants_impl, )*
+ _ => Ok(()),
+ }
+ }
+ }
+
+ fn derive_struct(
+ name_str: &str,
+ fields: &syn::Fields,
+ ) -> TokenStream {
+ match *fields {
+ syn::Fields::Named(ref f) => derive_fields(
+ name_str,
+ Fields::new(f.named.iter(), Some(syn::Token!(self)(Span::call_site()))),
+ ),
+ syn::Fields::Unnamed(ref f) => derive_fields(
+ name_str,
+ Fields::new(f.unnamed.iter(), None),
+ ),
+ syn::Fields::Unit => derive_fields(
+ name_str,
+ Fields::Indexed { indices: vec![] },
+ ),
+ }
+ }
+}
diff --git a/substrate/core/primitives/debug-derive/src/lib.rs b/substrate/core/primitives/debug-derive/src/lib.rs
new file mode 100644
index 0000000000..5e6cf6098b
--- /dev/null
+++ b/substrate/core/primitives/debug-derive/src/lib.rs
@@ -0,0 +1,44 @@
+// Copyright 2019 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 .
+
+//! Macros to derive runtime debug implementation.
+//!
+//! This custom derive implements a `core::fmt::Debug` trait,
+//! but in case the `std` feature is enabled the implementation
+//! will actually print out the structure as regular `derive(Debug)`
+//! would do. If `std` is disabled the implementation will be empty.
+//!
+//! This behaviour is useful to prevent bloating the runtime WASM
+//! blob from unneeded code.
+//!
+//! ```rust
+//! #[derive(substrate_debug_derive::RuntimeDebug)]
+//! struct MyStruct;
+//!
+//! assert_eq!(format!("{:?}", MyStruct), "MyStruct");
+//! ```
+
+extern crate proc_macro;
+
+mod impls;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(RuntimeDebug)]
+pub fn debug_derive(input: TokenStream) -> TokenStream {
+ impls::debug_derive(syn::parse_macro_input!(input))
+}
+
diff --git a/substrate/core/primitives/debug-derive/tests/tests.rs b/substrate/core/primitives/debug-derive/tests/tests.rs
new file mode 100644
index 0000000000..63ad6a3e8d
--- /dev/null
+++ b/substrate/core/primitives/debug-derive/tests/tests.rs
@@ -0,0 +1,63 @@
+// Copyright 2019 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 .
+
+use substrate_debug_derive::RuntimeDebug;
+
+#[derive(RuntimeDebug)]
+struct Unnamed(u64, String);
+
+#[derive(RuntimeDebug)]
+struct Named {
+ a: u64,
+ b: String,
+}
+
+#[derive(RuntimeDebug)]
+enum EnumLongName {
+ A,
+ B(A, String),
+ VariantLongName {
+ a: A,
+ b: String,
+ },
+}
+
+
+#[test]
+fn should_display_proper_debug() {
+ use self::EnumLongName as Enum;
+
+ assert_eq!(
+ format!("{:?}", Unnamed(1, "abc".into())),
+ "Unnamed(1, \"abc\")"
+ );
+ assert_eq!(
+ format!("{:?}", Named { a: 1, b: "abc".into() }),
+ "Named { a: 1, b: \"abc\" }"
+ );
+ assert_eq!(
+ format!("{:?}", Enum::::A),
+ "EnumLongName::A"
+ );
+ assert_eq!(
+ format!("{:?}", Enum::B(1, "abc".into())),
+ "EnumLongName::B(1, \"abc\")"
+ );
+ assert_eq!(
+ format!("{:?}", Enum::VariantLongName { a: 1, b: "abc".into() }),
+ "EnumLongName::VariantLongName { a: 1, b: \"abc\" }"
+ );
+}
diff --git a/substrate/core/primitives/src/crypto.rs b/substrate/core/primitives/src/crypto.rs
index 8a336783b7..588f3bc6e2 100644
--- a/substrate/core/primitives/src/crypto.rs
+++ b/substrate/core/primitives/src/crypto.rs
@@ -43,7 +43,7 @@ pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold r
pub const DEV_ADDRESS: &str = "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV";
/// The infallible type.
-#[derive(Debug)]
+#[derive(crate::RuntimeDebug)]
pub enum Infallible {}
/// The length of the junction identifier. Note that this is also referred to as the
@@ -743,7 +743,7 @@ pub trait CryptoType {
/// Values whose first character is `_` are reserved for private use and won't conflict with any
/// public modules.
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(crate::RuntimeDebug)]
pub struct KeyTypeId(pub [u8; 4]);
impl From for KeyTypeId {
diff --git a/substrate/core/primitives/src/ed25519.rs b/substrate/core/primitives/src/ed25519.rs
index b674a150c4..ff3b21e160 100644
--- a/substrate/core/primitives/src/ed25519.rs
+++ b/substrate/core/primitives/src/ed25519.rs
@@ -130,12 +130,17 @@ impl std::fmt::Display for Public {
}
}
-#[cfg(feature = "std")]
-impl std::fmt::Debug for Public {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+impl rstd::fmt::Debug for Public {
+ #[cfg(feature = "std")]
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
let s = self.to_ss58check();
write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8])
}
+
+ #[cfg(not(feature = "std"))]
+ fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
+ Ok(())
+ }
}
#[cfg(feature = "std")]
@@ -223,11 +228,16 @@ impl AsMut<[u8]> for Signature {
}
}
-#[cfg(feature = "std")]
-impl std::fmt::Debug for Signature {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+impl rstd::fmt::Debug for Signature {
+ #[cfg(feature = "std")]
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0))
}
+
+ #[cfg(not(feature = "std"))]
+ fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
+ Ok(())
+ }
}
#[cfg(feature = "std")]
diff --git a/substrate/core/primitives/src/hexdisplay.rs b/substrate/core/primitives/src/hexdisplay.rs
index 87be587a7d..6765ce517e 100644
--- a/substrate/core/primitives/src/hexdisplay.rs
+++ b/substrate/core/primitives/src/hexdisplay.rs
@@ -24,8 +24,8 @@ impl<'a> HexDisplay<'a> {
pub fn from(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) }
}
-impl<'a> ::core::fmt::Display for HexDisplay<'a> {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
+impl<'a> rstd::fmt::Display for HexDisplay<'a> {
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::fmt::Error> {
if self.0.len() < 1027 {
for byte in self.0 {
f.write_fmt(format_args!("{:02x}", byte))?;
@@ -43,8 +43,8 @@ impl<'a> ::core::fmt::Display for HexDisplay<'a> {
}
}
-impl<'a> core::fmt::Debug for HexDisplay<'a> {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
+impl<'a> rstd::fmt::Debug for HexDisplay<'a> {
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::fmt::Error> {
for byte in self.0 {
f.write_fmt(format_args!("{:02x}", byte))?;
}
diff --git a/substrate/core/primitives/src/lib.rs b/substrate/core/primitives/src/lib.rs
index 0a1f80aaa9..48d3d998fa 100644
--- a/substrate/core/primitives/src/lib.rs
+++ b/substrate/core/primitives/src/lib.rs
@@ -42,6 +42,8 @@ pub use serde;// << for macro
#[doc(hidden)]
pub use codec::{Encode, Decode};// << for macro
+pub use substrate_debug_derive::RuntimeDebug;
+
#[cfg(feature = "std")]
pub use impl_serde::serialize as bytes;
@@ -116,8 +118,8 @@ impl ExecutionContext {
}
/// Hex-serialized shim for `Vec`.
-#[derive(PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord))]
+#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord))]
pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec);
impl From> for Bytes {
@@ -162,8 +164,8 @@ pub enum NativeOrEncoded {
}
#[cfg(feature = "std")]
-impl ::std::fmt::Debug for NativeOrEncoded {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+impl rstd::fmt::Debug for NativeOrEncoded {
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f)
}
}
@@ -229,3 +231,58 @@ pub trait TypeId {
/// Simple 4 byte identifier.
const TYPE_ID: [u8; 4];
}
+
+/// A log level matching the one from `log` crate.
+///
+/// Used internally by `runtime_io::log` method.
+#[repr(u32)]
+pub enum LogLevel {
+ /// `Error` log level.
+ Error = 1,
+ /// `Warn` log level.
+ Warn = 2,
+ /// `Info` log level.
+ Info = 3,
+ /// `Debug` log level.
+ Debug = 4,
+ /// `Trace` log level.
+ Trace = 5,
+}
+
+impl From for LogLevel {
+ fn from(val: u32) -> Self {
+ match val {
+ x if x == LogLevel::Warn as u32 => LogLevel::Warn,
+ x if x == LogLevel::Info as u32 => LogLevel::Info,
+ x if x == LogLevel::Debug as u32 => LogLevel::Debug,
+ x if x == LogLevel::Trace as u32 => LogLevel::Trace,
+ _ => LogLevel::Error,
+ }
+ }
+}
+
+impl From for LogLevel {
+ fn from(l: log::Level) -> Self {
+ use log::Level::*;
+ match l {
+ Error => Self::Error,
+ Warn => Self::Warn,
+ Info => Self::Info,
+ Debug => Self::Debug,
+ Trace => Self::Trace,
+ }
+ }
+}
+
+impl From for log::Level {
+ fn from(l: LogLevel) -> Self {
+ use self::LogLevel::*;
+ match l {
+ Error => Self::Error,
+ Warn => Self::Warn,
+ Info => Self::Info,
+ Debug => Self::Debug,
+ Trace => Self::Trace,
+ }
+ }
+}
diff --git a/substrate/core/primitives/src/offchain.rs b/substrate/core/primitives/src/offchain.rs
index 84fee530f6..27bd29a00d 100644
--- a/substrate/core/primitives/src/offchain.rs
+++ b/substrate/core/primitives/src/offchain.rs
@@ -18,12 +18,12 @@
use codec::{Encode, Decode};
use rstd::{prelude::{Vec, Box}, convert::TryFrom};
+use crate::RuntimeDebug;
pub use crate::crypto::KeyTypeId;
/// A type of supported crypto.
-#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
#[repr(C)]
pub enum StorageKind {
/// Persistent storage is non-revertible and not fork-aware. It means that any value
@@ -59,8 +59,8 @@ impl From for u32 {
}
/// Opaque type for offchain http requests.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-#[cfg_attr(feature = "std", derive(Debug, Hash))]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Hash))]
pub struct HttpRequestId(pub u16);
impl From for u32 {
@@ -70,8 +70,7 @@ impl From for u32 {
}
/// An error enum returned by some http methods.
-#[derive(Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)]
#[repr(C)]
pub enum HttpError {
/// The requested action couldn't been completed within a deadline.
@@ -102,8 +101,7 @@ impl From for u32 {
}
/// Status of the HTTP request
-#[derive(Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug)]
pub enum HttpRequestStatus {
/// Deadline was reached while we waited for this request to finish.
///
@@ -149,8 +147,7 @@ impl TryFrom for HttpRequestStatus {
/// A blob to hold information about the local node's network state
/// without committing to its format.
-#[derive(Clone, Eq, PartialEq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)]
pub struct OpaqueNetworkState {
/// PeerId of the local node.
pub peer_id: OpaquePeerId,
@@ -159,8 +156,7 @@ pub struct OpaqueNetworkState {
}
/// Simple blob to hold a `PeerId` without committing to its format.
-#[derive(Default, Clone, Eq, PartialEq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Default, Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)]
pub struct OpaquePeerId(pub Vec);
impl OpaquePeerId {
@@ -171,8 +167,7 @@ impl OpaquePeerId {
}
/// Simple blob to hold a `Multiaddr` without committing to its format.
-#[derive(Clone, Eq, PartialEq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)]
pub struct OpaqueMultiaddr(pub Vec);
impl OpaqueMultiaddr {
@@ -183,13 +178,11 @@ impl OpaqueMultiaddr {
}
/// Opaque timestamp type
-#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug)]
pub struct Timestamp(u64);
/// Duration type
-#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Default, RuntimeDebug)]
pub struct Duration(u64);
impl Duration {
diff --git a/substrate/core/primitives/src/sandbox.rs b/substrate/core/primitives/src/sandbox.rs
index e47a30ca5b..dd91ad6a1f 100644
--- a/substrate/core/primitives/src/sandbox.rs
+++ b/substrate/core/primitives/src/sandbox.rs
@@ -21,12 +21,12 @@ use rstd::vec::Vec;
/// Error error that can be returned from host function.
#[derive(Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(crate::RuntimeDebug)]
pub struct HostError;
/// Representation of a typed wasm value.
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(crate::RuntimeDebug)]
pub enum TypedValue {
/// Value of 32-bit signed or unsigned integer.
#[codec(index = "1")]
@@ -86,7 +86,7 @@ impl From for ::wasmi::RuntimeValue {
///
/// Basically a `TypedValue` plus `Unit`, for functions which return nothing.
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(crate::RuntimeDebug)]
pub enum ReturnValue {
/// For returning nothing.
Unit,
@@ -119,7 +119,7 @@ fn return_value_encoded_max_size() {
/// Describes an entity to define or import into the environment.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(crate::RuntimeDebug)]
pub enum ExternEntity {
/// Function that is specified by an index in a default table of
/// a module that creates the sandbox.
@@ -137,7 +137,7 @@ pub enum ExternEntity {
/// Each entry has a two-level name and description of an entity
/// being defined.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(crate::RuntimeDebug)]
pub struct Entry {
/// Module name of which corresponding entity being defined.
pub module_name: Vec,
@@ -149,7 +149,7 @@ pub struct Entry {
/// Definition of runtime that could be used by sandboxed code.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(crate::RuntimeDebug)]
pub struct EnvironmentDefinition {
/// Vector of all entries in the environment definition.
pub entries: Vec,
diff --git a/substrate/core/primitives/src/sr25519.rs b/substrate/core/primitives/src/sr25519.rs
index ed8bb72c9e..f2160b88b7 100644
--- a/substrate/core/primitives/src/sr25519.rs
+++ b/substrate/core/primitives/src/sr25519.rs
@@ -129,12 +129,20 @@ impl std::fmt::Display for Public {
}
}
-#[cfg(feature = "std")]
-impl std::fmt::Debug for Public {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> ::std::fmt::Result {
+#[cfg(not(feature = "std"))]
+use core as std;
+
+impl rstd::fmt::Debug for Public {
+ #[cfg(feature = "std")]
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
let s = self.to_ss58check();
write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8])
}
+
+ #[cfg(not(feature = "std"))]
+ fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
+ Ok(())
+ }
}
#[cfg(feature = "std")]
@@ -231,11 +239,16 @@ impl From for Signature {
}
}
-#[cfg(feature = "std")]
-impl std::fmt::Debug for Signature {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+impl rstd::fmt::Debug for Signature {
+ #[cfg(feature = "std")]
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0))
}
+
+ #[cfg(not(feature = "std"))]
+ fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
+ Ok(())
+ }
}
#[cfg(feature = "std")]
diff --git a/substrate/core/primitives/storage/Cargo.toml b/substrate/core/primitives/storage/Cargo.toml
index 5b1ed37d6a..7bb2b95623 100644
--- a/substrate/core/primitives/storage/Cargo.toml
+++ b/substrate/core/primitives/storage/Cargo.toml
@@ -9,6 +9,7 @@ description = "Storage related primitives"
rstd = { package = "sr-std", path = "../../sr-std", default-features = false }
serde = { version = "1.0.101", optional = true, features = ["derive"] }
impl-serde = { version = "0.2.1", optional = true }
+substrate-debug-derive = { version = "2.0.0", path = "../debug-derive" }
[features]
default = [ "std" ]
diff --git a/substrate/core/primitives/storage/src/lib.rs b/substrate/core/primitives/storage/src/lib.rs
index 334779ed5f..dcdc223994 100644
--- a/substrate/core/primitives/storage/src/lib.rs
+++ b/substrate/core/primitives/storage/src/lib.rs
@@ -20,27 +20,29 @@
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
+use substrate_debug_derive::RuntimeDebug;
use rstd::{vec::Vec, borrow::Cow};
/// Storage key.
-#[derive(PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))]
+#[derive(PartialEq, Eq, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))]
pub struct StorageKey(
#[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))]
pub Vec,
);
/// Storage data associated to a [`StorageKey`].
-#[derive(PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord, Clone))]
+#[derive(PartialEq, Eq, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))]
pub struct StorageData(
#[cfg_attr(feature = "std", serde(with="impl_serde::serialize"))]
pub Vec,
);
/// Storage change set
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, PartialEq, Eq))]
+#[derive(RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize, PartialEq, Eq))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
pub struct StorageChangeSet {
/// Block hash
diff --git a/substrate/core/sr-arithmetic/Cargo.toml b/substrate/core/sr-arithmetic/Cargo.toml
index d98404db94..3962daf493 100644
--- a/substrate/core/sr-arithmetic/Cargo.toml
+++ b/substrate/core/sr-arithmetic/Cargo.toml
@@ -5,11 +5,12 @@ authors = ["Parity Technologies "]
edition = "2018"
[dependencies]
-num-traits = { version = "0.2.8", default-features = false }
-serde = { version = "1.0.101", optional = true, features = ["derive"] }
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
-rstd = { package = "sr-std", path = "../sr-std", default-features = false }
integer-sqrt = "0.1.2"
+num-traits = { version = "0.2.8", default-features = false }
+rstd = { package = "sr-std", path = "../sr-std", default-features = false }
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+substrate-debug-derive = { path = "../primitives/debug-derive", default-features = false }
[dev-dependencies]
primitive-types = "0.6.0"
@@ -19,8 +20,9 @@ rand = "0.7.2"
bench = []
default = ["std"]
std = [
- "serde",
+ "codec/std",
"num-traits/std",
"rstd/std",
- "codec/std",
+ "serde",
+ "substrate-debug-derive/std",
]
diff --git a/substrate/core/sr-arithmetic/src/biguint.rs b/substrate/core/sr-arithmetic/src/biguint.rs
index d90ad4862b..b7d93c2f0d 100644
--- a/substrate/core/sr-arithmetic/src/biguint.rs
+++ b/substrate/core/sr-arithmetic/src/biguint.rs
@@ -427,8 +427,8 @@ impl BigUint {
}
}
-#[cfg(feature = "std")]
impl rstd::fmt::Debug for BigUint {
+ #[cfg(feature = "std")]
fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result {
write!(
f,
@@ -437,6 +437,12 @@ impl rstd::fmt::Debug for BigUint {
u128::try_from(self.clone()).unwrap_or(0),
)
}
+
+ #[cfg(not(feature = "std"))]
+ fn fmt(&self, _: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result {
+ Ok(())
+ }
+
}
impl PartialEq for BigUint {
diff --git a/substrate/core/sr-arithmetic/src/fixed64.rs b/substrate/core/sr-arithmetic/src/fixed64.rs
index 7dfc8414d2..3bac75898e 100644
--- a/substrate/core/sr-arithmetic/src/fixed64.rs
+++ b/substrate/core/sr-arithmetic/src/fixed64.rs
@@ -144,11 +144,16 @@ impl CheckedAdd for Fixed64 {
}
}
-#[cfg(feature = "std")]
impl rstd::fmt::Debug for Fixed64 {
- fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result {
+ #[cfg(feature = "std")]
+ fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000)
}
+
+ #[cfg(not(feature = "std"))]
+ fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
+ Ok(())
+ }
}
#[cfg(test)]
diff --git a/substrate/core/sr-arithmetic/src/per_things.rs b/substrate/core/sr-arithmetic/src/per_things.rs
index afd8100a84..2dd1e62d0b 100644
--- a/substrate/core/sr-arithmetic/src/per_things.rs
+++ b/substrate/core/sr-arithmetic/src/per_things.rs
@@ -20,14 +20,15 @@ use serde::{Serialize, Deserialize};
use rstd::{ops, prelude::*, convert::TryInto};
use codec::{Encode, Decode, CompactAs};
use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating};
+use substrate_debug_derive::RuntimeDebug;
macro_rules! implement_per_thing {
($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => {
/// A fixed point representation of a number between in the range [0, 1].
///
#[doc = $title]
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Ord, PartialOrd))]
- #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, CompactAs)]
+ #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Ord, PartialOrd))]
+ #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, CompactAs)]
pub struct $name($type);
impl $name {
@@ -189,7 +190,7 @@ macro_rules! implement_per_thing {
#[cfg(test)]
mod $test_mod {
use codec::{Encode, Decode};
- use super::{$name, Saturating};
+ use super::{$name, Saturating, RuntimeDebug};
use crate::traits::Zero;
@@ -208,7 +209,7 @@ macro_rules! implement_per_thing {
assert!(<$upper_type>::from($max).checked_mul($max.into()).is_some());
}
- #[derive(Encode, Decode, PartialEq, Eq, Debug)]
+ #[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)]
struct WithCompact {
data: T,
}
diff --git a/substrate/core/sr-arithmetic/src/rational128.rs b/substrate/core/sr-arithmetic/src/rational128.rs
index 706d6a5eba..3247321199 100644
--- a/substrate/core/sr-arithmetic/src/rational128.rs
+++ b/substrate/core/sr-arithmetic/src/rational128.rs
@@ -17,10 +17,10 @@
use rstd::{cmp::Ordering, prelude::*};
use crate::helpers_128bit;
use num_traits::Zero;
+use substrate_debug_derive::RuntimeDebug;
/// A wrapper for any rational number with a 128 bit numerator and denominator.
-#[derive(Clone, Copy, Default, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, Copy, Default, Eq, RuntimeDebug)]
pub struct Rational128(u128, u128);
impl Rational128 {
diff --git a/substrate/core/sr-io/Cargo.toml b/substrate/core/sr-io/Cargo.toml
index e2b681b75b..4d140d289d 100644
--- a/substrate/core/sr-io/Cargo.toml
+++ b/substrate/core/sr-io/Cargo.toml
@@ -9,15 +9,16 @@ edition = "2018"
rustc_version = "0.2.3"
[dependencies]
-rstd = { package = "sr-std", path = "../sr-std", default-features = false }
-primitives = { package = "substrate-primitives", path = "../primitives", default-features = false }
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false }
hash-db = { version = "0.15.2", default-features = false }
+primitives = { package = "substrate-primitives", path = "../primitives", default-features = false }
+rstd = { package = "sr-std", path = "../sr-std", default-features = false }
libsecp256k1 = { version = "0.3.0", optional = true }
tiny-keccak = { version = "1.5.0", optional = true }
substrate-state-machine = { path = "../state-machine", optional = true }
trie = { package = "substrate-trie", path = "../trie", optional = true }
externalities = { package = "substrate-externalities", path = "../externalities", optional = true }
+log = { version = "0.4.8", optional = true }
[features]
default = ["std"]
@@ -31,6 +32,7 @@ std = [
"libsecp256k1",
"tiny-keccak",
"externalities",
+ "log",
]
nightly = []
strict = []
diff --git a/substrate/core/sr-io/src/lib.rs b/substrate/core/sr-io/src/lib.rs
index 24f964c7b5..b0274286dc 100644
--- a/substrate/core/sr-io/src/lib.rs
+++ b/substrate/core/sr-io/src/lib.rs
@@ -33,6 +33,7 @@ use primitives::{
offchain::{
Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState,
},
+ LogLevel,
};
/// Error verifying ECDSA signature
@@ -158,6 +159,20 @@ export_api! {
fn print_utf8(utf8: &[u8]);
/// Print any `u8` slice as hex.
fn print_hex(data: &[u8]);
+
+ /// Request to print a log message (stderr) on the host.
+ ///
+ /// Note that this will be only displayed if the host
+ /// is enabed to display log messages with given
+ /// level and target.
+ ///
+ /// Instead of using directly, prefer setting up `RuntimeLogger`
+ /// and using `log` macros.
+ fn log(
+ level: LogLevel,
+ target: &[u8],
+ message: &[u8]
+ );
}
}
diff --git a/substrate/core/sr-io/with_std.rs b/substrate/core/sr-io/with_std.rs
index e431ae1f6e..de40115cbe 100644
--- a/substrate/core/sr-io/with_std.rs
+++ b/substrate/core/sr-io/with_std.rs
@@ -192,6 +192,22 @@ impl OtherApi for () {
fn print_hex(data: &[u8]) {
println!("{}", HexDisplay::from(&data));
}
+
+ fn log(
+ level: LogLevel,
+ target: &[u8],
+ message: &[u8],
+ ) {
+ let target = std::str::from_utf8(target).unwrap_or("invalid utf8");
+ let msg = std::str::from_utf8(message).unwrap_or("invalid utf8");
+
+ log::log!(
+ target: target,
+ log::Level::from(level),
+ "{}",
+ msg,
+ )
+ }
}
impl CryptoApi for () {
diff --git a/substrate/core/sr-io/without_std.rs b/substrate/core/sr-io/without_std.rs
index 90ec5a9ee4..789098185e 100644
--- a/substrate/core/sr-io/without_std.rs
+++ b/substrate/core/sr-io/without_std.rs
@@ -160,6 +160,14 @@ pub mod ext {
fn ext_print_hex(data: *const u8, len: u32);
/// Print a number
fn ext_print_num(value: u64);
+ /// Print a log line if logging for given level and target is enabled.
+ fn ext_log(
+ level: u32,
+ target_data: *const u8,
+ target_len: u32,
+ message_data: *const u8,
+ message_len: u32,
+ );
/// Set value for key in storage.
fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32);
@@ -780,6 +788,22 @@ impl OtherApi for () {
ext_print_hex.get()(data.as_ptr(), data.len() as u32);
}
}
+
+ fn log(
+ level: LogLevel,
+ target: &[u8],
+ message: &[u8]
+ ) {
+ unsafe {
+ ext_log.get()(
+ level as u32,
+ target.as_ptr(),
+ target.len() as u32,
+ message.as_ptr(),
+ message.len() as u32,
+ )
+ }
+ }
}
impl HashingApi for () {
diff --git a/substrate/core/sr-primitives/Cargo.toml b/substrate/core/sr-primitives/Cargo.toml
index 249b89acee..d330301426 100644
--- a/substrate/core/sr-primitives/Cargo.toml
+++ b/substrate/core/sr-primitives/Cargo.toml
@@ -26,13 +26,13 @@ substrate-offchain = { path = "../offchain" }
bench = []
default = ["std"]
std = [
- "serde",
- "log",
- "rstd/std",
- "runtime_io/std",
- "codec/std",
- "primitives/std",
"app-crypto/std",
"arithmetic/std",
+ "codec/std",
+ "log",
+ "primitives/std",
"rand",
+ "rstd/std",
+ "runtime_io/std",
+ "serde",
]
diff --git a/substrate/core/sr-primitives/src/curve.rs b/substrate/core/sr-primitives/src/curve.rs
index dc6316bd47..6f25af3e10 100644
--- a/substrate/core/sr-primitives/src/curve.rs
+++ b/substrate/core/sr-primitives/src/curve.rs
@@ -20,8 +20,7 @@ use crate::{Perbill, traits::{SimpleArithmetic, SaturatedConversion}};
use core::ops::Sub;
/// Piecewise Linear function in [0, 1] -> [0, 1].
-#[cfg_attr(feature = "std", derive(Debug))]
-#[derive(PartialEq, Eq)]
+#[derive(PartialEq, Eq, primitives::RuntimeDebug)]
pub struct PiecewiseLinear<'a> {
/// Array of points. Must be in order from the lowest abscissas to the highest.
pub points: &'a [(Perbill, Perbill)]
diff --git a/substrate/core/sr-primitives/src/generic/block.rs b/substrate/core/sr-primitives/src/generic/block.rs
index 29fcaab572..3383e25760 100644
--- a/substrate/core/sr-primitives/src/generic/block.rs
+++ b/substrate/core/sr-primitives/src/generic/block.rs
@@ -23,13 +23,14 @@ use std::fmt;
use serde::{Deserialize, Serialize};
use rstd::prelude::*;
+use primitives::RuntimeDebug;
use crate::codec::{Codec, Encode, Decode};
use crate::traits::{self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize};
use crate::Justification;
/// Something to identify a block.
-#[derive(PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize))]
+#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub enum BlockId {
@@ -61,8 +62,8 @@ impl fmt::Display for BlockId {
}
/// Abstraction over a substrate block.
-#[derive(PartialEq, Eq, Clone, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
+#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Block {
@@ -99,8 +100,8 @@ where
}
/// Abstraction over a substrate block and justification.
-#[derive(PartialEq, Eq, Clone, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
+#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct SignedBlock {
diff --git a/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs b/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs
index e8d41325c4..1e030ea1d8 100644
--- a/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs
+++ b/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs
@@ -26,8 +26,7 @@ use crate::transaction_validity::TransactionValidity;
/// Definition of something that the external world might want to say; its
/// 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(Debug))]
+#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)]
pub struct CheckedExtrinsic {
/// 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).
diff --git a/substrate/core/sr-primitives/src/generic/digest.rs b/substrate/core/sr-primitives/src/generic/digest.rs
index d2974444e2..83f2c6f174 100644
--- a/substrate/core/sr-primitives/src/generic/digest.rs
+++ b/substrate/core/sr-primitives/src/generic/digest.rs
@@ -23,10 +23,11 @@ use rstd::prelude::*;
use crate::ConsensusEngineId;
use crate::codec::{Decode, Encode, Input, Error};
+use primitives::RuntimeDebug;
/// Generic header digest.
-#[derive(PartialEq, Eq, Clone, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
+#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Digest {
/// A list of logs in the digest.
pub logs: Vec>,
@@ -72,8 +73,7 @@ impl Digest {
/// Digest item that is able to encode/decode 'system' digest items and
/// provide opaque access to other items.
-#[derive(PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
pub enum DigestItem {
/// System digest item that contains the root of changes trie at given
/// block. It is created for every block iff runtime supports changes
@@ -123,8 +123,7 @@ impl<'a, Hash: Decode> serde::Deserialize<'a> for DigestItem {
/// A 'referencing view' for digest item. Does not own its contents. Used by
/// final runtime implementations for encoding/decoding its log items.
-#[derive(PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
pub enum DigestItemRef<'a, Hash: 'a> {
/// Reference to `DigestItem::ChangesTrieRoot`.
ChangesTrieRoot(&'a Hash),
diff --git a/substrate/core/sr-primitives/src/generic/era.rs b/substrate/core/sr-primitives/src/generic/era.rs
index 7308a8adc5..305951b1ee 100644
--- a/substrate/core/sr-primitives/src/generic/era.rs
+++ b/substrate/core/sr-primitives/src/generic/era.rs
@@ -28,8 +28,8 @@ pub type Period = u64;
pub type Phase = u64;
/// An era to describe the longevity of a transaction.
-#[derive(PartialEq, Eq, Clone, Copy)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
+#[derive(PartialEq, Eq, Clone, Copy, primitives::RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Era {
/// The transaction is valid forever. The genesis hash must be present in the signed content.
Immortal,
diff --git a/substrate/core/sr-primitives/src/generic/header.rs b/substrate/core/sr-primitives/src/generic/header.rs
index e9a8405fe2..75994749c5 100644
--- a/substrate/core/sr-primitives/src/generic/header.rs
+++ b/substrate/core/sr-primitives/src/generic/header.rs
@@ -18,20 +18,21 @@
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
-#[cfg(feature = "std")]
-use log::debug;
use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error};
use crate::traits::{
- self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Hash as HashT, MaybeSerializeDebug,
- MaybeSerializeDebugButNotDeserialize
+ self, Member, SimpleArithmetic, SimpleBitOps, Hash as HashT,
+ MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay,
};
use crate::generic::Digest;
use primitives::U256;
-use core::convert::TryFrom;
+use rstd::{
+ convert::TryFrom,
+ fmt::Debug,
+};
/// Abstraction over a block header for a substrate chain.
-#[derive(PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
+#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Header + TryFrom, Hash: HashT> {
@@ -103,11 +104,11 @@ impl codec::EncodeLike for Header where
{}
impl traits::Header for Header where
- Number: Member + MaybeSerializeDebug + rstd::hash::Hash + MaybeDisplay +
+ Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + MaybeDisplay +
SimpleArithmetic + Codec + Copy + Into + TryFrom,
Hash: HashT,
Hash::Output: Default + rstd::hash::Hash + Copy + Member +
- MaybeSerializeDebugButNotDeserialize + MaybeDisplay + SimpleBitOps + Codec,
+ MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec,
{
type Number = Number;
type Hash = ::Output;
@@ -127,15 +128,12 @@ impl traits::Header for Header where
fn digest(&self) -> &Digest { &self.digest }
- #[cfg(feature = "std")]
fn digest_mut(&mut self) -> &mut Digest {
- debug!(target: "header", "Retrieving mutable reference to digest");
+ #[cfg(feature = "std")]
+ log::debug!(target: "header", "Retrieving mutable reference to digest");
&mut self.digest
}
- #[cfg(not(feature = "std"))]
- fn digest_mut(&mut self) -> &mut Digest { &mut self.digest }
-
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
diff --git a/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs
index c5ee76e21c..d50314f33b 100644
--- a/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs
+++ b/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs
@@ -16,10 +16,8 @@
//! Generic implementation of an unchecked (pre-verification) extrinsic.
-#[cfg(feature = "std")]
-use std::fmt;
-
use rstd::prelude::*;
+use rstd::fmt;
use runtime_io::blake2_256;
use codec::{Decode, Encode, EncodeLike, Input, Error};
use crate::{
@@ -264,7 +262,6 @@ impl s
}
}
-#[cfg(feature = "std")]
impl fmt::Debug
for UncheckedExtrinsic
where
diff --git a/substrate/core/sr-primitives/src/lib.rs b/substrate/core/sr-primitives/src/lib.rs
index 590b6fedd7..ea295fbea6 100644
--- a/substrate/core/sr-primitives/src/lib.rs
+++ b/substrate/core/sr-primitives/src/lib.rs
@@ -62,6 +62,9 @@ pub use generic::{DigestItem, Digest};
pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType}};
pub use app_crypto::RuntimeAppPublic;
+/// Re-export `RuntimeDebug`, to avoid dependency clutter.
+pub use primitives::RuntimeDebug;
+
/// Re-export top-level arithmetic stuff.
pub use arithmetic::{
Perquintill, Perbill, Permill, Percent,
@@ -166,8 +169,7 @@ impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) {
pub type ConsensusEngineId = [u8; 4];
/// Signature verify that can work with any known signature types..
-#[derive(Eq, PartialEq, Clone, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug)]
pub enum MultiSignature {
/// An Ed25519 signature.
Ed25519(ed25519::Signature),
@@ -194,8 +196,8 @@ impl Default for MultiSignature {
}
/// Public key for any known crypto algorithm.
-#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum MultiSigner {
/// An Ed25519 identity.
Ed25519(ed25519::Public),
@@ -260,8 +262,8 @@ impl Verify for MultiSignature {
}
/// Signature verify that can work with any known signature types..
-#[derive(Eq, PartialEq, Clone, Default, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
+#[derive(Eq, PartialEq, Clone, Default, Encode, Decode, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct AnySignature(H512);
impl Verify for AnySignature {
@@ -289,8 +291,8 @@ impl From for AnySignature {
}
}
-#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize))]
+#[derive(Eq, PartialEq, Clone, Copy, Decode, Encode, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize))]
/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic).
pub enum ApplyError {
/// General error to do with the permissions of the sender.
@@ -341,8 +343,8 @@ impl From for ApplyOutcome {
/// Result from attempt to apply an extrinsic.
pub type ApplyResult = Result;
-#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize))]
+#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize))]
/// Reason why a dispatch call failed
pub struct DispatchError {
/// Module index, matching the metadata module index
@@ -564,13 +566,19 @@ macro_rules! assert_eq_error_rate {
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
pub struct OpaqueExtrinsic(pub Vec);
-#[cfg(feature = "std")]
-impl std::fmt::Debug for OpaqueExtrinsic {
- fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
+impl rstd::fmt::Debug for OpaqueExtrinsic {
+ #[cfg(feature = "std")]
+ fn fmt(&self, fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
write!(fmt, "{}", primitives::hexdisplay::HexDisplay::from(&self.0))
}
+
+ #[cfg(not(feature = "std"))]
+ fn fmt(&self, _fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result {
+ Ok(())
+ }
}
+
#[cfg(feature = "std")]
impl ::serde::Serialize for OpaqueExtrinsic {
fn serialize
(&self, seq: S) -> Result where S: ::serde::Serializer {
diff --git a/substrate/core/sr-primitives/src/offchain/http.rs b/substrate/core/sr-primitives/src/offchain/http.rs
index b68cf28365..77e514d653 100644
--- a/substrate/core/sr-primitives/src/offchain/http.rs
+++ b/substrate/core/sr-primitives/src/offchain/http.rs
@@ -51,6 +51,7 @@ use rstd::str;
use rstd::prelude::Vec;
#[cfg(not(feature = "std"))]
use rstd::prelude::vec;
+use primitives::RuntimeDebug;
use primitives::offchain::{
Timestamp,
HttpRequestId as RequestId,
@@ -59,8 +60,7 @@ use primitives::offchain::{
};
/// Request method (HTTP verb)
-#[derive(Clone, PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, PartialEq, Eq, RuntimeDebug)]
pub enum Method {
/// GET request
Get,
@@ -93,8 +93,7 @@ mod header {
use super::*;
/// A header type.
- #[derive(Clone, PartialEq, Eq)]
- #[cfg_attr(feature = "std", derive(Debug))]
+ #[derive(Clone, PartialEq, Eq, RuntimeDebug)]
pub struct Header {
name: Vec,
value: Vec,
@@ -128,8 +127,7 @@ mod header {
}
/// An HTTP request builder.
-#[derive(Clone, PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, PartialEq, Eq, RuntimeDebug)]
pub struct Request<'a, T = Vec<&'static [u8]>> {
/// Request method
pub method: Method,
@@ -249,8 +247,7 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator- > Request<'a, T> {
}
/// A request error
-#[derive(Clone, PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, PartialEq, Eq, RuntimeDebug)]
pub enum Error {
/// Deadline has been reached.
DeadlineReached,
@@ -261,8 +258,7 @@ pub enum Error {
}
/// A struct representing an uncompleted http request.
-#[derive(PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(PartialEq, Eq, RuntimeDebug)]
pub struct PendingRequest {
/// Request ID
pub id: RequestId,
@@ -323,7 +319,7 @@ impl PendingRequest {
}
/// A HTTP response.
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(RuntimeDebug)]
pub struct Response {
/// Request id
pub id: RequestId,
@@ -452,8 +448,7 @@ impl Iterator for ResponseBody {
}
/// A collection of Headers in the response.
-#[derive(Clone, PartialEq, Eq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, PartialEq, Eq, RuntimeDebug)]
pub struct Headers {
/// Raw headers
pub raw: Vec<(Vec, Vec)>,
@@ -483,8 +478,7 @@ impl Headers {
}
/// A custom iterator traversing all the headers.
-#[derive(Clone)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Clone, RuntimeDebug)]
pub struct HeadersIterator<'a> {
collection: &'a [(Vec, Vec)],
index: Option,
diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs
index a384c95e19..0497f094d2 100644
--- a/substrate/core/sr-primitives/src/traits.rs
+++ b/substrate/core/sr-primitives/src/traits.rs
@@ -17,10 +17,10 @@
//! Primitives for the runtime modules.
use rstd::prelude::*;
-use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}};
+use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug};
use runtime_io;
#[cfg(feature = "std")]
-use std::fmt::{Debug, Display};
+use std::fmt::Display;
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize, de::DeserializeOwned};
use primitives::{self, Hasher, Blake2Hasher, TypeId};
@@ -147,7 +147,7 @@ pub trait Lookup {
/// context.
pub trait StaticLookup {
/// Type to lookup from.
- type Source: Codec + Clone + PartialEq + MaybeDebug;
+ type Source: Codec + Clone + PartialEq + Debug;
/// Type to lookup into.
type Target;
/// Attempt a lookup.
@@ -159,7 +159,7 @@ pub trait StaticLookup {
/// A lookup implementation returning the input value.
#[derive(Default)]
pub struct IdentityLookup(PhantomData);
-impl StaticLookup for IdentityLookup {
+impl StaticLookup for IdentityLookup {
type Source = T;
type Target = T;
fn lookup(x: T) -> Result { Ok(x) }
@@ -323,10 +323,10 @@ pub trait OffchainWorker {
/// Abstraction around hashing
// Stupid bug in the Rust compiler believes derived
// traits must be fulfilled by all type parameters.
-pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq {
+pub trait Hash: 'static + MaybeSerializeDeserialize + Debug + Clone + Eq + PartialEq {
/// The hash type produced.
- type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy
- + Default + Encode + Decode;
+ type Output: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash
+ + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode;
/// The associated hash_db Hasher type.
type Hasher: Hasher;
@@ -353,8 +353,8 @@ pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq {
}
/// Blake2-256 Hash implementation.
-#[derive(PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
+#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct BlakeTwo256;
impl Hash for BlakeTwo256 {
@@ -410,7 +410,7 @@ impl CheckEqual for primitives::H256 {
}
}
-impl CheckEqual for super::generic::DigestItem where H: Encode {
+impl CheckEqual for super::generic::DigestItem where H: Encode {
#[cfg(feature = "std")]
fn check_equal(&self, other: &Self) {
if self != other {
@@ -447,23 +447,17 @@ macro_rules! impl_maybe_marker {
}
impl_maybe_marker!(
- /// A type that implements Debug when in std environment.
- MaybeDebug: Debug;
-
/// A type that implements Display when in std environment.
MaybeDisplay: Display;
/// A type that implements Hash when in std environment.
- MaybeHash: ::rstd::hash::Hash;
+ MaybeHash: rstd::hash::Hash;
/// A type that implements Serialize when in std environment.
MaybeSerialize: Serialize;
/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
- MaybeSerializeDebug: Debug, DeserializeOwned, Serialize;
-
- /// A type that implements Serialize and Debug when in std environment.
- MaybeSerializeDebugButNotDeserialize: Debug, Serialize
+ MaybeSerializeDeserialize: DeserializeOwned, Serialize
);
/// A type that provides a randomness beacon.
@@ -483,8 +477,8 @@ pub trait RandomnessBeacon {
}
/// A type that can be used in runtime structures.
-pub trait Member: Send + Sync + Sized + MaybeDebug + Eq + PartialEq + Clone + 'static {}
-impl Member for T {}
+pub trait Member: Send + Sync + Sized + Debug + Eq + PartialEq + Clone + 'static {}
+impl Member for T {}
/// Determine if a `MemberId` is a valid member.
pub trait IsMember {
@@ -497,11 +491,13 @@ pub trait IsMember {
/// `parent_hash`, as well as a `digest` and a block `number`.
///
/// You can also create a `new` one from those fields.
-pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static {
+pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static {
/// Header number.
- type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec;
+ type Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash
+ + Copy + MaybeDisplay + SimpleArithmetic + Codec;
/// Header hash type
- type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
+ type Hash: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash
+ + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
/// Hashing algorithm
type Hashing: Hash