Improve event json metadata (#710)

* Introduce `impl_event!` for declaring the Event/RawEvent for a module

* Implements a function for generating the event json metadata

* Update runtime `json_metadata` to include the new event json metadata

* Switch to `impl_event!` for new modules

* Remove unused module declaration in `impl_event!`

* Rename `impl_event!` to `decl_event!`

* Fixes some style nits
This commit is contained in:
Bastian Köcher
2018-09-11 14:05:09 +02:00
committed by Gav Wood
parent da56ae7e46
commit fd2ec13ed8
14 changed files with 522 additions and 277 deletions
+4 -1
View File
@@ -802,6 +802,9 @@ mod tests {
client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap();
assert_eq!(client.json_metadata(&BlockId::Number(1)).unwrap(), r#"{ "events": "events" }"#); assert_eq!(
client.json_metadata(&BlockId::Number(1)).unwrap(),
r#"{ "events": { "name": "Test", "events": { "event": hallo } } }"#
);
} }
} }
+205 -23
View File
@@ -14,6 +14,123 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>. // along with Substrate. If not, see <http://www.gnu.org/licenses/>.
/// Implement an `Event`/`RawEvent` for a module.
#[macro_export]
macro_rules! decl_event {
(
$(#[$attr:meta])*
pub enum Event<$( $evt_generic_param:ident )*> with RawEvent<$( $generic_param:ident ),*>
where $( <$generic:ident as $trait:path>::$trait_type:ident),* {
$(
$(#[doc = $doc_attr:tt])*
$event:ident( $( $param:path ),* ),
)*
}
) => {
pub type Event<$( $evt_generic_param )*> = RawEvent<$( <$generic as $trait>::$trait_type ),*>;
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
$(#[$attr])*
pub enum RawEvent<$( $generic_param ),*> {
$(
$( #[doc = $doc_attr] )*
$event($( $param ),*),
)*
}
impl<$( $generic_param ),*> From<RawEvent<$( $generic_param ),*>> for () {
fn from(_: RawEvent<$( $generic_param ),*>) -> () { () }
}
impl<$( $generic_param ),*> RawEvent<$( $generic_param ),*> {
#[allow(dead_code)]
pub fn event_json_metadata() -> &'static str {
concat!(
"{",
__impl_event_json_metadata!("";
$(
$event ( $( $param ),* );
__function_doc_to_json!(""; $($doc_attr)*);
)*
),
" }"
)
}
}
};
(
$(#[$attr:meta])*
pub enum Event {
$(
$(#[doc = $doc_attr:tt])*
$event:ident,
)*
}
) => {
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
$(#[$attr])*
pub enum Event {
$(
$( #[doc = $doc_attr] )*
$event,
)*
}
impl From<Event> for () {
fn from(_: Event) -> () { () }
}
impl Event {
#[allow(dead_code)]
pub fn event_json_metadata() -> &'static str {
concat!(
"{",
__impl_event_json_metadata!("";
$(
$event;
__function_doc_to_json!(""; $($doc_attr)*);
)*
),
" }"
)
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! __impl_event_json_metadata {
(
$prefix_str:expr;
$event:ident( $first_param:path $(, $param:path )* );
$event_doc:expr;
$( $rest:tt )*
) => {
concat!($prefix_str, " ", "\"", stringify!($event), r#"": { "params": [ ""#,
stringify!($first_param), "\""
$(, concat!(", \"", stringify!($param), "\"") )*, r#" ], "description": ["#,
$event_doc, " ] }",
__impl_event_json_metadata!(","; $( $rest )*)
)
};
(
$prefix_str:expr;
$event:ident;
$event_doc:expr;
$( $rest:tt )*
) => {
concat!($prefix_str, " ", "\"", stringify!($event),
r#"": { "params": null, "description": ["#, $event_doc, " ] }",
__impl_event_json_metadata!(","; $( $rest )*)
)
};
(
$prefix_str:expr;
) => {
""
}
}
#[macro_export] #[macro_export]
macro_rules! impl_outer_event { macro_rules! impl_outer_event {
($(#[$attr:meta])* pub enum $name:ident for $runtime:ident { $( $module:ident ),* }) => { ($(#[$attr:meta])* pub enum $name:ident for $runtime:ident { $( $module:ident ),* }) => {
@@ -54,39 +171,84 @@ macro_rules! __impl_outer_event_json_metadata {
) => { ) => {
impl $runtime { impl $runtime {
#[allow(dead_code)] #[allow(dead_code)]
pub fn outer_event_json_metadata() -> &'static str { pub fn outer_event_json_metadata() -> (&'static str, &'static [(&'static str, fn() -> &'static str)]) {
concat!(r#"{ "name": ""#, stringify!($event_name), r#"", "items": { "#, static METADATA: &[(&str, fn() -> &'static str)] = &[
r#""system": "system::Event""#, ("system", system::Event::event_json_metadata)
$(concat!(", \"", stringify!($module), r#"": ""#, $(
stringify!($module), "::Event<", stringify!($runtime), r#">""#),)* , (
" } }") stringify!($module),
$module::Event::<$runtime>::event_json_metadata
)
)*
];
(
stringify!($event_name),
METADATA
)
} }
} }
} }
} }
#[cfg(test)] #[cfg(test)]
#[allow(dead_code)]
mod tests { mod tests {
use serde; use serde;
use serde_json; use serde_json;
mod system { mod system {
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] pub trait Trait {
pub struct Event; type Origin;
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
decl_event!(
pub enum Event {
SystemEvent,
}
);
} }
mod event_module { mod event_module {
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] pub trait Trait {
pub struct Event<T> { type Origin;
t: T, type Balance;
} }
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
decl_event!(
pub enum Event<T> with RawEvent<Balance>
where <T as Trait>::Balance
{
/// Hi, I am a comment.
TestEvent(Balance),
}
);
} }
mod event_module2 { mod event_module2 {
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] pub trait Trait {
pub struct Event<T> { type Origin;
t: T, type Balance;
} }
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
decl_event!(
pub enum Event<T> with RawEvent<Balance>
where <T as Trait>::Balance
{
TestEvent(Balance),
}
);
} }
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)]
@@ -98,19 +260,39 @@ mod tests {
} }
} }
const EXPECTED_METADATA: &str = concat!( impl event_module::Trait for TestRuntime {
r#"{ "name": "TestEvent", "items": { "#, type Origin = u32;
r#""system": "system::Event", "#, type Balance = u32;
r#""event_module": "event_module::Event<TestRuntime>", "#, }
r#""event_module2": "event_module2::Event<TestRuntime>" "#,
r#"} }"# impl event_module2::Trait for TestRuntime {
type Origin = u32;
type Balance = u32;
}
impl system::Trait for TestRuntime {
type Origin = u32;
}
const EXPECTED_METADATA: (&str, &[(&str, &str)]) = (
"TestEvent", &[
("system", r#"{ "SystemEvent": { "params": null, "description": [ ] } }"#),
("event_module", r#"{ "TestEvent": { "params": [ "Balance" ], "description": [ " Hi, I am a comment." ] } }"#),
("event_module2", r#"{ "TestEvent": { "params": [ "Balance" ], "description": [ ] } }"#),
]
); );
#[test] #[test]
fn outer_event_json_metadata() { fn outer_event_json_metadata() {
let metadata = TestRuntime::outer_event_json_metadata(); let metadata = TestRuntime::outer_event_json_metadata();
assert_eq!(EXPECTED_METADATA, metadata); assert_eq!(EXPECTED_METADATA.0, metadata.0);
let _: serde::de::IgnoredAny = assert_eq!(EXPECTED_METADATA.1.len(), metadata.1.len());
serde_json::from_str(metadata).expect("Is valid json syntax");
for (expected, got) in EXPECTED_METADATA.1.iter().zip(metadata.1.iter()) {
assert_eq!(expected.0, got.0);
assert_eq!(expected.1, got.1());
let _: serde::de::IgnoredAny =
serde_json::from_str(got.1()).expect(&format!("Is valid json syntax: {}", got.1()));
}
} }
} }
@@ -40,9 +40,11 @@ macro_rules! impl_json_metadata {
) => { ) => {
impl $runtime { impl $runtime {
pub fn json_metadata() -> $crate::metadata::Vec<$crate::metadata::JSONMetadata> { pub fn json_metadata() -> $crate::metadata::Vec<$crate::metadata::JSONMetadata> {
let events = Self::outer_event_json_metadata();
__impl_json_metadata!($runtime; __impl_json_metadata!($runtime;
$crate::metadata::JSONMetadata::Events { $crate::metadata::JSONMetadata::Events {
events: Self::outer_event_json_metadata() name: events.0,
events: events.1,
}; };
$( $rest )* $( $rest )*
) )
@@ -52,10 +54,10 @@ macro_rules! impl_json_metadata {
} }
/// The metadata of a runtime encoded as JSON. /// The metadata of a runtime encoded as JSON.
#[derive(Eq, PartialEq)] #[derive(Eq)]
#[cfg_attr(feature = "std", derive(Debug))] #[cfg_attr(feature = "std", derive(Debug))]
pub enum JSONMetadata { pub enum JSONMetadata {
Events { events: &'static str }, Events { name: &'static str, events: &'static [(&'static str, fn() -> &'static str)] },
Module { module: &'static str, prefix: &'static str }, Module { module: &'static str, prefix: &'static str },
ModuleWithStorage { module: &'static str, prefix: &'static str, storage: &'static str } ModuleWithStorage { module: &'static str, prefix: &'static str, storage: &'static str }
} }
@@ -63,9 +65,14 @@ pub enum JSONMetadata {
impl Encode for JSONMetadata { impl Encode for JSONMetadata {
fn encode_to<W: Output>(&self, dest: &mut W) { fn encode_to<W: Output>(&self, dest: &mut W) {
match self { match self {
JSONMetadata::Events { events } => { JSONMetadata::Events { name, events } => {
0i8.encode_to(dest); 0i8.encode_to(dest);
events.encode_to(dest); name.encode_to(dest);
events.iter().fold(0u32, |count, _| count + 1).encode_to(dest);
events
.iter()
.map(|(module, data)| (module, data()))
.for_each(|val| val.encode_to(dest));
}, },
JSONMetadata::Module { module, prefix } => { JSONMetadata::Module { module, prefix } => {
1i8.encode_to(dest); 1i8.encode_to(dest);
@@ -82,11 +89,39 @@ impl Encode for JSONMetadata {
} }
} }
impl PartialEq<JSONMetadata> for JSONMetadata {
fn eq(&self, other: &JSONMetadata) -> bool {
match (self, other) {
(
JSONMetadata::Events { name: lname, events: left },
JSONMetadata::Events { name: rname, events: right }
) => {
lname == rname && left.iter().zip(right.iter()).fold(true, |res, (l, r)| {
res && l.0 == r.0 && l.1() == r.1()
})
},
(
JSONMetadata::Module { prefix: lpre, module: lmod },
JSONMetadata::Module { prefix: rpre, module: rmod }
) => {
lpre == rpre && lmod == rmod
},
(
JSONMetadata::ModuleWithStorage { prefix: lpre, module: lmod, storage: lstore },
JSONMetadata::ModuleWithStorage { prefix: rpre, module: rmod, storage: rstore }
) => {
lpre == rpre && lmod == rmod && lstore == rstore
},
_ => false,
}
}
}
/// Utility struct for making `JSONMetadata` decodeable. /// Utility struct for making `JSONMetadata` decodeable.
#[derive(Eq, PartialEq, Debug)] #[derive(Eq, PartialEq, Debug)]
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub enum JSONMetadataDecodable { pub enum JSONMetadataDecodable {
Events { events: String }, Events { name: String, events: Vec<(String, String)> },
Module { module: String, prefix: String }, Module { module: String, prefix: String },
ModuleWithStorage { module: String, prefix: String, storage: String } ModuleWithStorage { module: String, prefix: String, storage: String }
} }
@@ -97,15 +132,33 @@ impl JSONMetadataDecodable {
/// The first value of the tuple is the name of the metadata type and the second in the JSON string. /// The first value of the tuple is the name of the metadata type and the second in the JSON string.
pub fn into_json_string(self) -> (&'static str, String) { pub fn into_json_string(self) -> (&'static str, String) {
match self { match self {
JSONMetadataDecodable::Events { events } => { JSONMetadataDecodable::Events { name, events } => {
("events", events) (
"events",
format!(
r#"{{ "name": "{}", "events": {{ {} }} }}"#, name,
events.iter().enumerate()
.fold(String::from(""), |mut json, (i, (name, data))| {
if i > 0 {
json.push_str(", ");
}
json.push_str(&format!(r#""{}": {}"#, name, data));
json
})
)
)
}, },
JSONMetadataDecodable::Module { prefix, module } => { JSONMetadataDecodable::Module { prefix, module } => {
("module", format!(r#"{{ "prefix": "{}", "module": {} }}"#, prefix, module)) ("module", format!(r#"{{ "prefix": "{}", "module": {} }}"#, prefix, module))
}, },
JSONMetadataDecodable::ModuleWithStorage { prefix, module, storage } => { JSONMetadataDecodable::ModuleWithStorage { prefix, module, storage } => {
("moduleWithStorage", (
format!(r#"{{ "prefix": "{}", "module": {}, "storage": {} }}"#, prefix, module, storage)) "moduleWithStorage",
format!(
r#"{{ "prefix": "{}", "module": {}, "storage": {} }}"#,
prefix, module, storage
)
)
} }
} }
} }
@@ -117,7 +170,8 @@ impl Decode for JSONMetadataDecodable {
i8::decode(input).and_then(|variant| { i8::decode(input).and_then(|variant| {
match variant { match variant {
0 => String::decode(input) 0 => String::decode(input)
.and_then(|events| Some(JSONMetadataDecodable::Events { events })), .and_then(|name| Vec::<(String, String)>::decode(input).map(|events| (name, events)))
.and_then(|(name, events)| Some(JSONMetadataDecodable::Events { name, events })),
1 => String::decode(input) 1 => String::decode(input)
.and_then(|prefix| String::decode(input).map(|v| (prefix, v))) .and_then(|prefix| String::decode(input).map(|v| (prefix, v)))
.and_then(|(prefix, module)| Some(JSONMetadataDecodable::Module { prefix, module })), .and_then(|(prefix, module)| Some(JSONMetadataDecodable::Module { prefix, module })),
@@ -136,10 +190,12 @@ impl PartialEq<JSONMetadata> for JSONMetadataDecodable {
fn eq(&self, other: &JSONMetadata) -> bool { fn eq(&self, other: &JSONMetadata) -> bool {
match (self, other) { match (self, other) {
( (
JSONMetadataDecodable::Events { events: left }, JSONMetadataDecodable::Events { name: lname, events: left },
JSONMetadata::Events { events: right } JSONMetadata::Events { name: rname, events: right }
) => { ) => {
left == right lname == rname && left.iter().zip(right.iter()).fold(true, |res, (l, r)| {
res && l.0 == r.0 && l.1 == r.1()
})
}, },
( (
JSONMetadataDecodable::Module { prefix: lpre, module: lmod }, JSONMetadataDecodable::Module { prefix: lpre, module: lmod },
@@ -228,21 +284,42 @@ macro_rules! __impl_json_metadata {
#[allow(dead_code)] #[allow(dead_code)]
mod tests { mod tests {
use super::*; use super::*;
use dispatch::Result; use serde;
use serde_json;
mod system { mod system {
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] pub trait Trait {
pub struct Event; type Origin;
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
decl_event!(
pub enum Event {
SystemEvent,
}
);
} }
mod event_module { mod event_module {
use super::*; use dispatch::Result;
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] pub trait Trait {
pub struct Event<T> { type Origin;
t: T, type Balance;
} }
decl_event!(
pub enum Event<T> with RawEvent<Balance>
where <T as Trait>::Balance
{
/// Hi, I am a comment.
TestEvent(Balance),
}
);
decl_module! { decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin { pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn aux_0(origin) -> Result; fn aux_0(origin) -> Result;
@@ -257,13 +334,19 @@ mod tests {
} }
mod event_module2 { mod event_module2 {
use super::*; pub trait Trait {
type Origin;
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] type Balance;
pub struct Event<T> {
t: T,
} }
decl_event!(
pub enum Event<T> with RawEvent<Balance>
where <T as Trait>::Balance
{
TestEvent(Balance),
}
);
decl_module! { decl_module! {
pub struct ModuleWithStorage<T: Trait> for enum Call where origin: T::Origin {} pub struct ModuleWithStorage<T: Trait> for enum Call where origin: T::Origin {}
} }
@@ -284,11 +367,17 @@ mod tests {
} }
} }
pub trait Trait { impl event_module::Trait for TestRuntime {
type Origin; type Origin = u32;
type Balance = u32;
} }
impl Trait for TestRuntime { impl event_module2::Trait for TestRuntime {
type Origin = u32;
type Balance = u32;
}
impl system::Trait for TestRuntime {
type Origin = u32; type Origin = u32;
} }
@@ -298,13 +387,26 @@ mod tests {
event_module2::ModuleWithStorage with Storage event_module2::ModuleWithStorage with Storage
); );
fn system_event_json() -> &'static str {
r#"{ "SystemEvent": { "params": null, "description": [ ] } }"#
}
fn event_module_event_json() -> &'static str {
r#"{ "TestEvent": { "params": [ "Balance" ], "description": [ " Hi, I am a comment." ] } }"#
}
fn event_module2_event_json() -> &'static str {
r#"{ "TestEvent": { "params": [ "Balance" ], "description": [ ] } }"#
}
const EXPECTED_METADATA: &[JSONMetadata] = &[ const EXPECTED_METADATA: &[JSONMetadata] = &[
JSONMetadata::Events { JSONMetadata::Events {
events: concat!( name: "TestEvent",
r#"{ "name": "TestEvent", "items": "#, events: &[
r#"{ "system": "system::Event", "#, ("system", system_event_json),
r#""event_module": "event_module::Event<TestRuntime>", "#, ("event_module", event_module_event_json),
r#""event_module2": "event_module2::Event<TestRuntime>" } }"#) ("event_module2", event_module2_event_json),
]
}, },
JSONMetadata::Module { JSONMetadata::Module {
module: concat!( module: concat!(
@@ -341,4 +443,17 @@ mod tests {
assert_eq!(&metadata_decoded.unwrap()[..], &metadata[..]); assert_eq!(&metadata_decoded.unwrap()[..], &metadata[..]);
} }
#[test]
fn into_json_string_is_valid_json() {
let metadata = TestRuntime::json_metadata();
let metadata_encoded = metadata.encode();
let metadata_decoded = Vec::<JSONMetadataDecodable>::decode(&mut &metadata_encoded[..]);
for mdata in metadata_decoded.unwrap().into_iter() {
let json = mdata.into_json_string();
let _: serde::de::IgnoredAny =
serde_json::from_str(&json.1).expect(&format!("Is valid json syntax: {}", json.1));
}
}
} }
+11 -21
View File
@@ -67,12 +67,6 @@ const RECLAIM_INDEX_MAGIC: usize = 0x69;
pub type Address<T> = RawAddress<<T as system::Trait>::AccountId, <T as Trait>::AccountIndex>; pub type Address<T> = RawAddress<<T as system::Trait>::AccountId, <T as Trait>::AccountIndex>;
pub type Event<T> = RawEvent<
<T as system::Trait>::AccountId,
<T as Trait>::AccountIndex,
<T as Trait>::Balance,
>;
/// The account with the given id was killed. /// The account with the given id was killed.
pub trait OnFreeBalanceZero<AccountId> { pub trait OnFreeBalanceZero<AccountId> {
/// The account was the given id was killed. /// The account was the given id was killed.
@@ -141,21 +135,17 @@ decl_module! {
} }
} }
/// An event in this module. decl_event!(
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub enum Event<T> with RawEvent<AccountId, AccountIndex, Balance>
#[derive(Encode, Decode, PartialEq, Eq, Clone)] where <T as system::Trait>::AccountId, <T as Trait>::AccountIndex, <T as Trait>::Balance {
pub enum RawEvent<AccountId, AccountIndex, Balance> { /// A new account was created.
/// A new account was created. NewAccount(AccountId, AccountIndex, NewAccountOutcome),
NewAccount(AccountId, AccountIndex, NewAccountOutcome), /// An account was reaped.
/// An account was reaped. ReapedAccount(AccountId),
ReapedAccount(AccountId), /// Transfer succeeded (from, to, value, fees).
/// Transfer succeeded (from, to, value, fees). Transfer(AccountId, AccountId, Balance, Balance),
Transfer(AccountId, AccountId, Balance, Balance), }
} );
impl<A, I, B> From<RawEvent<A, I, B>> for () {
fn from(_: RawEvent<A, I, B>) -> () { () }
}
decl_storage! { decl_storage! {
trait Store for Module<T: Trait> as Balances { trait Store for Module<T: Trait> as Balances {
@@ -47,29 +47,24 @@ pub enum Origin {
Members(u32), Members(u32),
} }
/// Outwardly visible event.
pub type Event<T> = RawEvent<<T as system::Trait>::Hash, <T as system::Trait>::AccountId>;
/// Event for this module. /// Event for this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] decl_event!(
#[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum Event<T> with RawEvent<Hash, AccountId>
pub enum RawEvent<Hash, AccountId> { where <T as system::Trait>::Hash, <T as system::Trait>::AccountId
/// A motion (given hash) has been proposed (by given account) with a threshold (given u32). {
Proposed(AccountId, ProposalIndex, Hash, u32), /// A motion (given hash) has been proposed (by given account) with a threshold (given u32).
/// A motion (given hash) has been voted on by given account, leaving Proposed(AccountId, ProposalIndex, Hash, u32),
/// a tally (yes votes and no votes given as u32s respectively). /// A motion (given hash) has been voted on by given account, leaving
Voted(AccountId, Hash, bool, u32, u32), /// a tally (yes votes and no votes given as u32s respectively).
/// A motion was approved by the required threshold. Voted(AccountId, Hash, bool, u32, u32),
Approved(Hash), /// A motion was approved by the required threshold.
/// A motion was not approved by the required threshold. Approved(Hash),
Disapproved(Hash), /// A motion was not approved by the required threshold.
/// A motion was executed; `bool` is true if returned without error. Disapproved(Hash),
Executed(Hash, bool), /// A motion was executed; `bool` is true if returned without error.
} Executed(Hash, bool),
}
impl<H, A> From<RawEvent<H, A>> for () { );
fn from(_: RawEvent<H, A>) -> () { () }
}
decl_module! { decl_module! {
#[cfg_attr(feature = "std", serde(bound(deserialize = "<T as Trait>::Proposal: ::serde::de::DeserializeOwned")))] #[cfg_attr(feature = "std", serde(bound(deserialize = "<T as Trait>::Proposal: ::serde::de::DeserializeOwned")))]
@@ -154,25 +154,21 @@ decl_storage! {
} }
} }
pub type Event<T> = RawEvent<<T as system::Trait>::AccountId>; decl_event!(
/// An event in this module.
/// An event in this module. pub enum Event<T> with RawEvent<AccountId>
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] where <T as system::Trait>::AccountId
#[derive(Encode, Decode, PartialEq, Eq, Clone)] {
pub enum RawEvent<AccountId> { /// reaped voter, reaper
/// reaped voter, reaper VoterReaped(AccountId, AccountId),
VoterReaped(AccountId, AccountId), /// slashed reaper
/// slashed reaper BadReaperSlashed(AccountId),
BadReaperSlashed(AccountId), /// A tally (for approval votes of council seat(s)) has started.
/// A tally (for approval votes of council seat(s)) has started. TallyStarted(u32),
TallyStarted(u32), /// A tally (for approval votes of council seat(s)) has ended (with one or more new members).
/// A tally (for approval votes of council seat(s)) has ended (with one or more new members). TallyFinalised(Vec<AccountId>, Vec<AccountId>),
TallyFinalised(Vec<AccountId>, Vec<AccountId>), }
} );
impl<N> From<RawEvent<N>> for () {
fn from(_: RawEvent<N>) -> () { () }
}
impl<T: Trait> Module<T> { impl<T: Trait> Module<T> {
@@ -53,21 +53,19 @@ decl_storage! {
} }
} }
pub type Event<T> = RawEvent<<T as system::Trait>::Hash>;
/// An event in this module. /// An event in this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] decl_event!(
#[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum Event<T> with RawEvent<Hash>
pub enum RawEvent<Hash> { where <T as system::Trait>::Hash
/// A voting tally has happened for a referendum cancelation vote. Last three are yes, no, abstain counts. {
TallyCancelation(Hash, u32, u32, u32), /// A voting tally has happened for a referendum cancelation vote.
/// A voting tally has happened for a referendum vote. Last three are yes, no, abstain counts. /// Last three are yes, no, abstain counts.
TallyReferendum(Hash, u32, u32, u32), TallyCancelation(Hash, u32, u32, u32),
} /// A voting tally has happened for a referendum vote.
/// Last three are yes, no, abstain counts.
impl<N> From<RawEvent<N>> for () { TallyReferendum(Hash, u32, u32, u32),
fn from(_: RawEvent<N>) -> () { () } }
} );
impl<T: Trait> Module<T> { impl<T: Trait> Module<T> {
@@ -108,26 +108,19 @@ decl_storage! {
} }
} }
/// An event in this module. decl_event!(
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] /// An event in this module.
#[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum Event<T> with RawEvent<Balance, AccountId>
pub enum RawEvent<Balance, AccountId> { where <T as balances::Trait>::Balance, <T as system::Trait>::AccountId
Tabled(PropIndex, Balance, Vec<AccountId>), {
Started(ReferendumIndex, VoteThreshold), Tabled(PropIndex, Balance, Vec<AccountId>),
Passed(ReferendumIndex), Started(ReferendumIndex, VoteThreshold),
NotPassed(ReferendumIndex), Passed(ReferendumIndex),
Cancelled(ReferendumIndex), NotPassed(ReferendumIndex),
Executed(ReferendumIndex, bool), Cancelled(ReferendumIndex),
} Executed(ReferendumIndex, bool),
}
impl<B, A> From<RawEvent<B, A>> for () { );
fn from(_: RawEvent<B, A>) -> () { () }
}
pub type Event<T> = RawEvent<
<T as balances::Trait>::Balance,
<T as system::Trait>::AccountId,
>;
impl<T: Trait> Module<T> { impl<T: Trait> Module<T> {
+9 -22
View File
@@ -117,31 +117,18 @@ decl_module! {
} }
} }
/// Exported Event type that's generic over the configuration trait.
// NOTE: External macro-fu expects this type to exist and be generic over
// the configuration trait.
pub type Event<T> = RawEvent<
<T as balances::Trait>::Balance,
>;
/// An event in this module. Events are simple means of reporting specific conditions and /// An event in this module. Events are simple means of reporting specific conditions and
/// circumstances that have happened that users, Dapps and/or chain explorers would find /// circumstances that have happened that users, Dapps and/or chain explorers would find
/// interesting and otherwise difficult to detect. /// interesting and otherwise difficult to detect.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] decl_event!(
#[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum Event<T> with RawEvent<B>
pub enum RawEvent<B> { where <T as balances::Trait>::Balance
// Just a normal `enum`, here's a dummy event to ensure it compiles. {
/// Dummy event, just here so there's a generic type that's used. // Just a normal `enum`, here's a dummy event to ensure it compiles.
Dummy(B), /// Dummy event, just here so there's a generic type that's used.
} Dummy(B),
}
// By convention we implement any trait for which a "null implementation" makes sense );
// for `()`. This is the case for conversion of module `Event` types and hook traits. It
// is helpful for test code and production configurations where no eventing is necessary
// or the hook is unused.
impl<B> From<RawEvent<B>> for () {
fn from(_: RawEvent<B>) -> () { () }
}
decl_storage! { decl_storage! {
// A macro for the Storage trait, and its implementation, for this module. // A macro for the Storage trait, and its implementation, for this module.
+9 -13
View File
@@ -73,8 +73,6 @@ pub trait Trait: timestamp::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>; type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
} }
pub type Event<T> = RawEvent<<T as system::Trait>::BlockNumber>;
decl_module! { decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin { pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn set_key(origin, key: T::SessionKey) -> Result; fn set_key(origin, key: T::SessionKey) -> Result;
@@ -85,17 +83,15 @@ decl_module! {
} }
/// An event in this module. /// An event in this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] decl_event!(
#[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum Event<T> with RawEvent<BlockNumber>
pub enum RawEvent<BlockNumber> { where <T as system::Trait>::BlockNumber
/// New session has happened. Note that the argument is the session index, not the block number {
/// as the type might suggest. /// New session has happened. Note that the argument is the session index, not the block
NewSession(BlockNumber), /// number as the type might suggest.
} NewSession(BlockNumber),
}
impl<N> From<RawEvent<N>> for () { );
fn from(_: RawEvent<N>) -> () { () }
}
decl_storage! { decl_storage! {
trait Store for Module<T: Trait> as Session { trait Store for Module<T: Trait> as Session {
+15 -19
View File
@@ -6,6 +6,8 @@
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// Substrate is distributed in the hope that it will be useful, // Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -64,11 +66,6 @@ pub use genesis_config::GenesisConfig;
const DEFAULT_MINIMUM_VALIDATOR_COUNT: usize = 4; const DEFAULT_MINIMUM_VALIDATOR_COUNT: usize = 4;
pub type Event<T> = RawEvent<
<T as balances::Trait>::Balance,
<T as system::Trait>::AccountId
>;
#[derive(PartialEq, Clone)] #[derive(PartialEq, Clone)]
#[cfg_attr(test, derive(Debug))] #[cfg_attr(test, derive(Debug))]
pub enum LockStatus<BlockNumber: Parameter> { pub enum LockStatus<BlockNumber: Parameter> {
@@ -122,20 +119,19 @@ decl_module! {
} }
/// An event in this module. /// An event in this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] decl_event!(
#[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum Event<T> with RawEvent<Balance, AccountId>
pub enum RawEvent<Balance, AccountId> { where <T as balances::Trait>::Balance, <T as system::Trait>::AccountId
/// All validators have been rewarded by the given balance. {
Reward(Balance), /// All validators have been rewarded by the given balance.
/// One validator (and their nominators) has been given a offline-warning (they're still within Reward(Balance),
/// their grace). The accrued number of slashes is recorded, too. /// One validator (and their nominators) has been given a offline-warning (they're still
OfflineWarning(AccountId, u32), /// within their grace). The accrued number of slashes is recorded, too.
/// One validator (and their nominators) has been slashed by the given amount. OfflineWarning(AccountId, u32),
OfflineSlash(AccountId, Balance), /// One validator (and their nominators) has been slashed by the given amount.
} OfflineSlash(AccountId, Balance),
impl<B, A> From<RawEvent<B, A>> for () { }
fn from(_: RawEvent<B, A>) -> () { () } );
}
pub type PairOf<T> = (T, T); pub type PairOf<T> = (T, T);
+8 -12
View File
@@ -111,18 +111,14 @@ pub struct EventRecord<E: Parameter + Member> {
} }
/// Event for the system module. /// Event for the system module.
#[derive(Encode, Decode, PartialEq, Eq, Clone)] decl_event!(
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub enum Event {
pub enum Event { /// An extrinsic completed successfully.
/// An extrinsic completed successfully. ExtrinsicSuccess,
ExtrinsicSuccess, /// An extrinsic failed.
/// An extrinsic failed. ExtrinsicFailed,
ExtrinsicFailed, }
} );
impl From<Event> for () {
fn from(_: Event) -> () { () }
}
/// Origin for the system module. /// Origin for the system module.
#[derive(PartialEq, Eq, Clone)] #[derive(PartialEq, Eq, Clone)]
+16 -24
View File
@@ -134,31 +134,23 @@ decl_storage! {
} }
} }
/// Exported Event type that's generic over the configuration trait.
pub type Event<T> = RawEvent<
<T as balances::Trait>::Balance,
<T as system::Trait>::AccountId,
>;
/// An event in this module. /// An event in this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] decl_event!(
#[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum Event<T> with RawEvent<Balance, AccountId>
pub enum RawEvent<Balance, AccountId> { where <T as balances::Trait>::Balance, <T as system::Trait>::AccountId
/// New proposal. {
Proposed(ProposalIndex), /// New proposal.
/// We have ended a spend period and will now allocate funds. Proposed(ProposalIndex),
Spending(Balance), /// We have ended a spend period and will now allocate funds.
/// Some funds have been allocated. Spending(Balance),
Awarded(ProposalIndex, Balance, AccountId), /// Some funds have been allocated.
/// Some of our funds have been burnt. Awarded(ProposalIndex, Balance, AccountId),
Burnt(Balance), /// Some of our funds have been burnt.
/// Spending has finished; this is the amount that rolls over until next spend. Burnt(Balance),
Rollover(Balance), /// Spending has finished; this is the amount that rolls over until next spend.
} Rollover(Balance),
}
impl<B, A> From<RawEvent<B, A>> for () { );
fn from(_: RawEvent<B, A>) -> () { () }
}
impl<T: Trait> Module<T> { impl<T: Trait> Module<T> {
/// Deposit one of this module's events. /// Deposit one of this module's events.
+7 -1
View File
@@ -134,13 +134,19 @@ pub fn run_tests(mut input: &[u8]) -> Vec<u8> {
[stxs.len() as u8].encode() [stxs.len() as u8].encode()
} }
fn test_event_json() -> &'static str {
"hallo"
}
pub mod api { pub mod api {
use system; use system;
impl_stubs!( impl_stubs!(
version => |()| super::version(), version => |()| super::version(),
json_metadata => |()| { json_metadata => |()| {
let mut vec = ::runtime_support::metadata::Vec::new(); let mut vec = ::runtime_support::metadata::Vec::new();
vec.push(::runtime_support::metadata::JSONMetadata::Events { events: r#""events""# }); vec.push(::runtime_support::metadata::JSONMetadata::Events {
name: "Test", events: &[ ("event", super::test_event_json) ]
});
vec vec
}, },
authorities => |()| system::authorities(), authorities => |()| system::authorities(),