Fix compact event field decoding (#384)

* Add basic event decoding test

* Failing compact event field test

* Fmt

* Fix compact event field decoding

* Remove println

* Add test for compact wrapper struct

* Revert "Add test for compact wrapper struct"

This reverts commit 4e8332ddcd9b758973bdecbea9901c4a378e26b7.

* Split compact tests and add multiple events test
This commit is contained in:
Andrew Jones
2022-01-07 14:20:42 +00:00
committed by GitHub
parent ca5345c47e
commit e8cbe467cb
2 changed files with 187 additions and 35 deletions
+186 -34
View File
@@ -253,10 +253,10 @@ where
} }
} }
} }
TypeDef::Compact(_compact) => { TypeDef::Compact(compact) => {
let inner = self let inner = self
.metadata .metadata
.resolve_type(type_id) .resolve_type(compact.type_param().id())
.ok_or(MetadataError::TypeNotFound(type_id))?; .ok_or(MetadataError::TypeNotFound(type_id))?;
let mut decode_compact_primitive = |primitive: &TypeDefPrimitive| { let mut decode_compact_primitive = |primitive: &TypeDefPrimitive| {
match primitive { match primitive {
@@ -339,35 +339,187 @@ pub enum EventsDecodingError {
InvalidCompactType(String), InvalidCompactType(String),
} }
// #[cfg(test)] #[cfg(test)]
// mod tests { mod tests {
// use super::*; use super::*;
// use std::convert::TryFrom; use crate::{
// Config,
// type DefaultConfig = crate::NodeTemplateRuntime; DefaultConfig,
// Phase,
// #[test] };
// fn test_decode_option() { use frame_metadata::{
// let decoder = EventsDecoder::<DefaultConfig>::new( v14::{
// Metadata::default(), ExtrinsicMetadata,
// ); PalletEventMetadata,
// PalletMetadata,
// let value = Some(0u8); RuntimeMetadataLastVersion,
// let input = value.encode(); },
// let mut output = Vec::<u8>::new(); RuntimeMetadataPrefixed,
// let mut errors = Vec::<RuntimeError>::new(); };
// use scale_info::{
// decoder meta_type,
// .decode_raw_bytes( TypeInfo,
// &[EventArg::Option(Box::new(EventArg::Primitive( };
// "u8".to_string(), use std::convert::TryFrom;
// )))],
// &mut &input[..], #[derive(Encode)]
// &mut output, pub struct EventRecord<E: Encode> {
// &mut errors, phase: Phase,
// ) pallet_index: u8,
// .unwrap(); event: E,
// topics: Vec<<DefaultConfig as Config>::Hash>,
// assert_eq!(output, vec![1, 0]); }
// }
// } fn event_record<E: Encode>(pallet_index: u8, event: E) -> EventRecord<E> {
EventRecord {
phase: Phase::Finalization,
pallet_index,
event,
topics: vec![],
}
}
fn pallet_metadata<E: TypeInfo + 'static>(pallet_index: u8) -> PalletMetadata {
let event = PalletEventMetadata {
ty: meta_type::<E>(),
};
PalletMetadata {
name: "Test",
storage: None,
calls: None,
event: Some(event),
constants: vec![],
error: None,
index: pallet_index,
}
}
fn init_decoder(pallets: Vec<PalletMetadata>) -> EventsDecoder<DefaultConfig> {
let extrinsic = ExtrinsicMetadata {
ty: meta_type::<()>(),
version: 0,
signed_extensions: vec![],
};
let v14 = RuntimeMetadataLastVersion::new(pallets, extrinsic, meta_type::<()>());
let runtime_metadata: RuntimeMetadataPrefixed = v14.into();
let metadata = Metadata::try_from(runtime_metadata).unwrap();
EventsDecoder::<DefaultConfig>::new(metadata)
}
#[test]
fn decode_single_event() {
#[derive(Clone, Encode, TypeInfo)]
enum Event {
A(u8),
}
let pallet_index = 0;
let pallet = pallet_metadata::<Event>(pallet_index);
let decoder = init_decoder(vec![pallet]);
let event = Event::A(1);
let encoded_event = event.encode();
let event_records = vec![event_record(pallet_index, event)];
let mut input = Vec::new();
event_records.encode_to(&mut input);
let events = decoder.decode_events(&mut &input[..]).unwrap();
assert_eq!(events[0].1.variant_index, encoded_event[0]);
assert_eq!(events[0].1.data.0, encoded_event[1..]);
}
#[test]
fn decode_multiple_events() {
#[derive(Clone, Encode, TypeInfo)]
enum Event {
A(u8),
B,
C { a: u32 },
}
let pallet_index = 0;
let pallet = pallet_metadata::<Event>(pallet_index);
let decoder = init_decoder(vec![pallet]);
let event1 = Event::A(1);
let event2 = Event::B;
let event3 = Event::C { a: 3 };
let encoded_event1 = event1.encode();
let encoded_event2 = event2.encode();
let encoded_event3 = event3.encode();
let event_records = vec![
event_record(pallet_index, event1),
event_record(pallet_index, event2),
event_record(pallet_index, event3),
];
let mut input = Vec::new();
event_records.encode_to(&mut input);
let events = decoder.decode_events(&mut &input[..]).unwrap();
assert_eq!(events[0].1.variant_index, encoded_event1[0]);
assert_eq!(events[0].1.data.0, encoded_event1[1..]);
assert_eq!(events[1].1.variant_index, encoded_event2[0]);
assert_eq!(events[1].1.data.0, encoded_event2[1..]);
assert_eq!(events[2].1.variant_index, encoded_event3[0]);
assert_eq!(events[2].1.data.0, encoded_event3[1..]);
}
#[test]
fn compact_event_field() {
#[derive(Clone, Encode, TypeInfo)]
enum Event {
A(#[codec(compact)] u32),
}
let pallet_index = 0;
let pallet = pallet_metadata::<Event>(pallet_index);
let decoder = init_decoder(vec![pallet]);
let event = Event::A(u32::MAX);
let encoded_event = event.encode();
let event_records = vec![event_record(pallet_index, event)];
let mut input = Vec::new();
event_records.encode_to(&mut input);
let events = decoder.decode_events(&mut &input[..]).unwrap();
assert_eq!(events[0].1.variant_index, encoded_event[0]);
assert_eq!(events[0].1.data.0, encoded_event[1..]);
}
#[test]
fn compact_wrapper_struct_field() {
#[derive(Clone, Encode, TypeInfo)]
enum Event {
A(#[codec(compact)] CompactWrapper),
}
#[derive(Clone, codec::CompactAs, Encode, TypeInfo)]
struct CompactWrapper(u64);
let pallet_index = 0;
let pallet = pallet_metadata::<Event>(pallet_index);
let decoder = init_decoder(vec![pallet]);
let event = Event::A(CompactWrapper(0));
let encoded_event = event.encode();
let event_records = vec![event_record(pallet_index, event)];
let mut input = Vec::new();
event_records.encode_to(&mut input);
let events = decoder.decode_events(&mut &input[..]).unwrap();
assert_eq!(events[0].1.variant_index, encoded_event[0]);
assert_eq!(events[0].1.data.0, encoded_event[1..]);
}
}
+1 -1
View File
@@ -166,7 +166,7 @@ impl codec::Encode for Encoded {
} }
/// A phase of a block's execution. /// A phase of a block's execution.
#[derive(Clone, Debug, Eq, PartialEq, Decode)] #[derive(Clone, Debug, Eq, PartialEq, Decode, Encode)]
pub enum Phase { pub enum Phase {
/// Applying an extrinsic. /// Applying an extrinsic.
ApplyExtrinsic(u32), ApplyExtrinsic(u32),