mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 12:11:09 +00:00
Fix decoding events via .as_root_event() and add test (#767)
* fix decoding events via as_root_event and add test * fmt and clippy * Update subxt/src/events/events_type.rs Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
@@ -201,10 +201,12 @@ pub struct EventDetails {
|
|||||||
all_bytes: Arc<[u8]>,
|
all_bytes: Arc<[u8]>,
|
||||||
// start of the bytes (phase, pallet/variant index and then fields and then topic to follow).
|
// start of the bytes (phase, pallet/variant index and then fields and then topic to follow).
|
||||||
start_idx: usize,
|
start_idx: usize,
|
||||||
// start of the fields (ie after phase nad pallet/variant index).
|
// start of the event (ie pallet/variant index and then the fields and topic after).
|
||||||
fields_start_idx: usize,
|
event_start_idx: usize,
|
||||||
|
// start of the fields (ie after phase and pallet/variant index).
|
||||||
|
event_fields_start_idx: usize,
|
||||||
// end of the fields.
|
// end of the fields.
|
||||||
fields_end_idx: usize,
|
event_fields_end_idx: usize,
|
||||||
// end of everything (fields + topics)
|
// end of everything (fields + topics)
|
||||||
end_idx: usize,
|
end_idx: usize,
|
||||||
metadata: Metadata,
|
metadata: Metadata,
|
||||||
@@ -221,10 +223,13 @@ impl EventDetails {
|
|||||||
let input = &mut &all_bytes[start_idx..];
|
let input = &mut &all_bytes[start_idx..];
|
||||||
|
|
||||||
let phase = Phase::decode(input)?;
|
let phase = Phase::decode(input)?;
|
||||||
|
|
||||||
|
let event_start_idx = all_bytes.len() - input.len();
|
||||||
|
|
||||||
let pallet_index = u8::decode(input)?;
|
let pallet_index = u8::decode(input)?;
|
||||||
let variant_index = u8::decode(input)?;
|
let variant_index = u8::decode(input)?;
|
||||||
|
|
||||||
let fields_start_idx = all_bytes.len() - input.len();
|
let event_fields_start_idx = all_bytes.len() - input.len();
|
||||||
|
|
||||||
// Get metadata for the event:
|
// Get metadata for the event:
|
||||||
let event_metadata = metadata.event(pallet_index, variant_index)?;
|
let event_metadata = metadata.event(pallet_index, variant_index)?;
|
||||||
@@ -246,7 +251,7 @@ impl EventDetails {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the end of the field bytes.
|
// the end of the field bytes.
|
||||||
let fields_end_idx = all_bytes.len() - input.len();
|
let event_fields_end_idx = all_bytes.len() - input.len();
|
||||||
|
|
||||||
// topics come after the event data in EventRecord. They aren't used for
|
// topics come after the event data in EventRecord. They aren't used for
|
||||||
// anything at the moment, so just decode and throw them away.
|
// anything at the moment, so just decode and throw them away.
|
||||||
@@ -259,8 +264,9 @@ impl EventDetails {
|
|||||||
phase,
|
phase,
|
||||||
index,
|
index,
|
||||||
start_idx,
|
start_idx,
|
||||||
fields_start_idx,
|
event_start_idx,
|
||||||
fields_end_idx,
|
event_fields_start_idx,
|
||||||
|
event_fields_end_idx,
|
||||||
end_idx,
|
end_idx,
|
||||||
all_bytes,
|
all_bytes,
|
||||||
metadata,
|
metadata,
|
||||||
@@ -281,14 +287,14 @@ impl EventDetails {
|
|||||||
pub fn pallet_index(&self) -> u8 {
|
pub fn pallet_index(&self) -> u8 {
|
||||||
// Note: never panics; we expect these bytes to exist
|
// Note: never panics; we expect these bytes to exist
|
||||||
// in order that the EventDetails could be created.
|
// in order that the EventDetails could be created.
|
||||||
self.all_bytes[self.fields_start_idx - 2]
|
self.all_bytes[self.event_fields_start_idx - 2]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The index of the event variant that the event originated from.
|
/// The index of the event variant that the event originated from.
|
||||||
pub fn variant_index(&self) -> u8 {
|
pub fn variant_index(&self) -> u8 {
|
||||||
// Note: never panics; we expect these bytes to exist
|
// Note: never panics; we expect these bytes to exist
|
||||||
// in order that the EventDetails could be created.
|
// in order that the EventDetails could be created.
|
||||||
self.all_bytes[self.fields_start_idx - 1]
|
self.all_bytes[self.event_fields_start_idx - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The name of the pallet from whence the Event originated.
|
/// The name of the pallet from whence the Event originated.
|
||||||
@@ -319,7 +325,7 @@ impl EventDetails {
|
|||||||
|
|
||||||
/// Return the bytes representing the fields stored in this event.
|
/// Return the bytes representing the fields stored in this event.
|
||||||
pub fn field_bytes(&self) -> &[u8] {
|
pub fn field_bytes(&self) -> &[u8] {
|
||||||
&self.all_bytes[self.fields_start_idx..self.fields_end_idx]
|
&self.all_bytes[self.event_fields_start_idx..self.event_fields_end_idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode and provide the event fields back in the form of a [`scale_value::Composite`]
|
/// Decode and provide the event fields back in the form of a [`scale_value::Composite`]
|
||||||
@@ -384,7 +390,7 @@ impl EventDetails {
|
|||||||
/// the pallet and event enum variants as well as the event fields). A compatible
|
/// the pallet and event enum variants as well as the event fields). A compatible
|
||||||
/// type for this is exposed via static codegen as a root level `Event` type.
|
/// type for this is exposed via static codegen as a root level `Event` type.
|
||||||
pub fn as_root_event<E: Decode>(&self) -> Result<E, CodecError> {
|
pub fn as_root_event<E: Decode>(&self) -> Result<E, CodecError> {
|
||||||
E::decode(&mut self.bytes())
|
E::decode(&mut &self.all_bytes[self.event_start_idx..self.event_fields_end_idx])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,6 +509,7 @@ mod tests {
|
|||||||
event_record,
|
event_record,
|
||||||
events,
|
events,
|
||||||
events_raw,
|
events_raw,
|
||||||
|
AllEvents,
|
||||||
},
|
},
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
@@ -572,6 +579,39 @@ mod tests {
|
|||||||
assert_eq!(actual_fields_no_context, expected.fields);
|
assert_eq!(actual_fields_no_context, expected.fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn statically_decode_single_root_event() {
|
||||||
|
#[derive(Clone, Debug, PartialEq, Decode, Encode, TypeInfo)]
|
||||||
|
enum Event {
|
||||||
|
A(u8, bool, Vec<String>),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create fake metadata that knows about our single event, above:
|
||||||
|
let metadata = metadata::<Event>();
|
||||||
|
|
||||||
|
// Encode our events in the format we expect back from a node, and
|
||||||
|
// construst an Events object to iterate them:
|
||||||
|
let event = Event::A(1, true, vec!["Hi".into()]);
|
||||||
|
let events = events::<Event>(
|
||||||
|
metadata,
|
||||||
|
vec![event_record(Phase::ApplyExtrinsic(123), event.clone())],
|
||||||
|
);
|
||||||
|
|
||||||
|
let ev = events
|
||||||
|
.iter()
|
||||||
|
.next()
|
||||||
|
.expect("one event expected")
|
||||||
|
.expect("event should be extracted OK");
|
||||||
|
|
||||||
|
// This is the line we're testing:
|
||||||
|
let decoded_event = ev
|
||||||
|
.as_root_event::<AllEvents<Event>>()
|
||||||
|
.expect("can decode event into root enum again");
|
||||||
|
|
||||||
|
// It should equal the event we put in:
|
||||||
|
assert_eq!(decoded_event, AllEvents::Test(event));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dynamically_decode_single_event() {
|
fn dynamically_decode_single_event() {
|
||||||
#[derive(Clone, Debug, PartialEq, Decode, Encode, TypeInfo)]
|
#[derive(Clone, Debug, PartialEq, Decode, Encode, TypeInfo)]
|
||||||
|
|||||||
Reference in New Issue
Block a user