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
.metadata
.resolve_type(type_id)
.resolve_type(compact.type_param().id())
.ok_or(MetadataError::TypeNotFound(type_id))?;
let mut decode_compact_primitive = |primitive: &TypeDefPrimitive| {
match primitive {
@@ -339,35 +339,187 @@ pub enum EventsDecodingError {
InvalidCompactType(String),
}
// #[cfg(test)]
// mod tests {
// use super::*;
// use std::convert::TryFrom;
//
// type DefaultConfig = crate::NodeTemplateRuntime;
//
// #[test]
// fn test_decode_option() {
// let decoder = EventsDecoder::<DefaultConfig>::new(
// Metadata::default(),
// );
//
// let value = Some(0u8);
// let input = value.encode();
// let mut output = Vec::<u8>::new();
// let mut errors = Vec::<RuntimeError>::new();
//
// decoder
// .decode_raw_bytes(
// &[EventArg::Option(Box::new(EventArg::Primitive(
// "u8".to_string(),
// )))],
// &mut &input[..],
// &mut output,
// &mut errors,
// )
// .unwrap();
//
// assert_eq!(output, vec![1, 0]);
// }
// }
#[cfg(test)]
mod tests {
use super::*;
use crate::{
Config,
DefaultConfig,
Phase,
};
use frame_metadata::{
v14::{
ExtrinsicMetadata,
PalletEventMetadata,
PalletMetadata,
RuntimeMetadataLastVersion,
},
RuntimeMetadataPrefixed,
};
use scale_info::{
meta_type,
TypeInfo,
};
use std::convert::TryFrom;
#[derive(Encode)]
pub struct EventRecord<E: Encode> {
phase: Phase,
pallet_index: u8,
event: E,
topics: Vec<<DefaultConfig as Config>::Hash>,
}
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.
#[derive(Clone, Debug, Eq, PartialEq, Decode)]
#[derive(Clone, Debug, Eq, PartialEq, Decode, Encode)]
pub enum Phase {
/// Applying an extrinsic.
ApplyExtrinsic(u32),