Skip to content

Commit

Permalink
Add hooks to register event types for decoding (paritytech#227)
Browse files Browse the repository at this point in the history
* Global registration of type segmenters for event decoding

* Perform type sizes check when building client

* Introduce EventTypeRegistry for global runtime type sizes

* Fmt

* Register runtime type sizes on creation of EventTypeRegistry

* Register more default dispatch types

* Add missing type sizes

* fmt

* Fix up register_type_size builder method

* Update doc comments

* Make register_default_type_sizes public

* Don't allow duplicate registered types

* Remove call to supertraits type registration, done manually in Runtime

* Fix tests and warnings

* Fix duplicate type registration

* Fmt

* review: use is_empty()

Co-authored-by: Niklas Adolfsson <[email protected]>

* Add panic docs

Co-authored-by: Niklas Adolfsson <[email protected]>
  • Loading branch information
ascjones and niklasad1 authored Feb 18, 2021
1 parent 2c8e521 commit de859e7
Show file tree
Hide file tree
Showing 19 changed files with 419 additions and 263 deletions.
2 changes: 1 addition & 1 deletion .rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn_single_line = false
where_single_line = false
imports_indent = "Block"
imports_layout = "Vertical" # changed
imports_granularity= "Crate" # changed
imports_granularity = "Crate" # changed
reorder_imports = true
reorder_modules = true
reorder_impl_items = false
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ codec = { package = "parity-scale-codec", version = "2.0.0", default-features =
# temporarily pinning funty via codec -> bitvec until https://github.com/myrrlyn/funty/issues/3
# and https://github.com/bitvecto-rs/bitvec/issues/105 are resolved
funty = "=1.1.0"
dyn-clone = "1.0.4"

frame-metadata = "13.0.0"
frame-support = "3.0.0"
Expand Down
5 changes: 1 addition & 4 deletions examples/transfer_subscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@
use sp_keyring::AccountKeyring;
use substrate_subxt::{
balances::{
BalancesEventsDecoder,
TransferCallExt,
TransferEvent,
},
sp_core::Decode,
ClientBuilder,
DefaultNodeRuntime,
EventSubscription,
EventsDecoder,
PairSigner,
};

Expand All @@ -38,8 +36,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

let client = ClientBuilder::<DefaultNodeRuntime>::new().build().await?;
let sub = client.subscribe_events().await?;
let mut decoder = EventsDecoder::<DefaultNodeRuntime>::new(client.metadata().clone());
decoder.with_balances();
let decoder = client.events_decoder();
let mut sub = EventSubscription::<DefaultNodeRuntime>::new(sub, decoder);
sub.filter_event::<TransferEvent<_>>();
client.transfer(&signer, &dest, 10_000).await?;
Expand Down
14 changes: 0 additions & 14 deletions proc-macro/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ pub fn call(s: Structure) -> TokenStream {
let generics = &s.ast().generics;
let params = utils::type_params(generics);
let module = utils::module_name(generics);
let with_module = format_ident!(
"with_{}",
utils::path_to_ident(module).to_string().to_snake_case()
);
let call_name = utils::ident_to_name(ident, "Call").to_snake_case();
let bindings = utils::bindings(&s);
let fields = utils::fields(&bindings);
Expand All @@ -51,11 +47,6 @@ pub fn call(s: Structure) -> TokenStream {
impl#generics #subxt::Call<T> for #ident<#(#params),*> {
const MODULE: &'static str = MODULE;
const FUNCTION: &'static str = #call_name;
fn events_decoder(
decoder: &mut #subxt::EventsDecoder<T>,
) {
decoder.#with_module();
}
}

/// Call extension trait.
Expand Down Expand Up @@ -118,11 +109,6 @@ mod tests {
impl<'a, T: Balances> substrate_subxt::Call<T> for TransferCall<'a, T> {
const MODULE: &'static str = MODULE;
const FUNCTION: &'static str = "transfer";
fn events_decoder(
decoder: &mut substrate_subxt::EventsDecoder<T>,
) {
decoder.with_balances();
}
}

/// Call extension trait.
Expand Down
9 changes: 4 additions & 5 deletions proc-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,16 @@ use synstructure::{
///
/// const MODULE: &str = "Herd";
///
/// // `EventsDecoder` extension trait.
/// pub trait HerdEventsDecoder {
/// // `EventTypeRegistry` extension trait.
/// pub trait HerdEventTypeRegistry {
/// // Registers this modules types.
/// fn with_herd(&mut self);
/// }
///
/// impl<T: Herd> HerdEventsDecoder for
/// substrate_subxt::EventsDecoder<T>
/// impl<T: Herd + Runtime> EventTypeRegistry for
/// substrate_subxt::EventTypeRegistry<T>
/// {
/// fn with_herd(&mut self) {
/// self.with_husbandry();
/// self.register_type_size::<T::Hooves>("Hooves");
/// self.register_type_size::<T::Wool>("Wool");
/// }
Expand Down
44 changes: 15 additions & 29 deletions proc-macro/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ fn ignore(attrs: &[syn::Attribute]) -> bool {
false
}

fn events_decoder_trait_name(module: &syn::Ident) -> syn::Ident {
format_ident!("{}EventsDecoder", module.to_string())
fn event_type_registry_trait_name(module: &syn::Ident) -> syn::Ident {
format_ident!("{}EventTypeRegistry", module.to_string())
}

fn with_module_ident(module: &syn::Ident) -> syn::Ident {
Expand Down Expand Up @@ -128,20 +128,9 @@ pub fn module(_args: TokenStream, tokens: TokenStream) -> TokenStream {
let subxt = utils::use_crate("substrate-subxt");
let module = &input.ident;
let module_name = module.to_string();
let module_events_decoder = events_decoder_trait_name(module);
let module_events_type_registry = event_type_registry_trait_name(module);
let with_module = with_module_ident(module);

let bounds = input.supertraits.iter().filter_map(|bound| {
if let syn::TypeParamBound::Trait(syn::TraitBound { path, .. }) = bound {
let module = utils::path_to_ident(path);
let with_module = with_module_ident(module);
Some(quote! {
self.#with_module();
})
} else {
None
}
});
let associated_types = input.items.iter().filter_map(|item| {
if let syn::TraitItem::Type(ty) = item {
if ignore(&ty.attrs) {
Expand All @@ -168,17 +157,16 @@ pub fn module(_args: TokenStream, tokens: TokenStream) -> TokenStream {

const MODULE: &str = #module_name;

/// `EventsDecoder` extension trait.
pub trait #module_events_decoder {
/// `EventTypeRegistry` extension trait.
pub trait #module_events_type_registry {
/// Registers this modules types.
fn #with_module(&mut self);
}

impl<T: #module> #module_events_decoder for
#subxt::EventsDecoder<T>
impl<T: #module + #subxt::Runtime> #module_events_type_registry for
#subxt::EventTypeRegistry<T>
{
fn #with_module(&mut self) {
#(#bounds)*
#(#associated_types)*
#(#types)*
}
Expand Down Expand Up @@ -221,17 +209,16 @@ mod tests {

const MODULE: &str = "Balances";

/// `EventsDecoder` extension trait.
pub trait BalancesEventsDecoder {
/// `EventTypeRegistry` extension trait.
pub trait BalancesEventTypeRegistry {
/// Registers this modules types.
fn with_balances(&mut self);
}

impl<T: Balances> BalancesEventsDecoder for
substrate_subxt::EventsDecoder<T>
impl<T: Balances + substrate_subxt::Runtime> BalancesEventTypeRegistry for
substrate_subxt::EventTypeRegistry<T>
{
fn with_balances(&mut self) {
self.with_system();
self.register_type_size::<T::Balance>("Balance");
}
}
Expand Down Expand Up @@ -262,17 +249,16 @@ mod tests {

const MODULE: &str = "Herd";

/// `EventsDecoder` extension trait.
pub trait HerdEventsDecoder {
/// `EventTypeRegistry` extension trait.
pub trait HerdEventTypeRegistry {
/// Registers this modules types.
fn with_herd(&mut self);
}

impl<T: Herd> HerdEventsDecoder for
substrate_subxt::EventsDecoder<T>
impl<T: Herd + substrate_subxt::Runtime> HerdEventTypeRegistry for
substrate_subxt::EventTypeRegistry<T>
{
fn with_herd(&mut self) {
self.with_husbandry();
self.register_type_size::<T::Hoves>("Hoves");
self.register_type_size::<T::Wool>("Wool");
}
Expand Down
5 changes: 1 addition & 4 deletions proc-macro/tests/balances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ use substrate_subxt::{
MaybeSerialize,
Member,
},
system::{
System,
SystemEventsDecoder,
},
system::System,
ClientBuilder,
KusamaRuntime,
PairSigner,
Expand Down
7 changes: 7 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ pub enum Error {
/// Metadata error.
#[error("Metadata error: {0}")]
Metadata(#[from] MetadataError),
/// Unregistered type sizes.
#[error(
"The following types do not have a type size registered: \
{0:?} \
Use `ClientBuilder::register_type_size` to register missing type sizes."
)]
MissingTypeSizes(Vec<String>),
/// Type size unavailable.
#[error("Type size unavailable while decoding event: {0:?}")]
TypeSizeUnavailable(String),
Expand Down
Loading

0 comments on commit de859e7

Please sign in to comment.