From 6e74a45019b8083374b84b29936693085420bcc1 Mon Sep 17 00:00:00 2001 From: James Wilson Date: Tue, 10 Jan 2023 16:56:34 +0000 Subject: [PATCH 1/3] fix decoding events via as_root_event and add test --- subxt/src/events/events_type.rs | 59 +++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/subxt/src/events/events_type.rs b/subxt/src/events/events_type.rs index 234f6aa7b5..1680be4f61 100644 --- a/subxt/src/events/events_type.rs +++ b/subxt/src/events/events_type.rs @@ -201,10 +201,12 @@ pub struct EventDetails { all_bytes: Arc<[u8]>, // start of the bytes (phase, pallet/variant index and then fields and then topic to follow). start_idx: usize, + // start of the event (ie pallet/variant index and then the fields and topic after). + event_start_idx: usize, // start of the fields (ie after phase nad pallet/variant index). - fields_start_idx: usize, + event_fields_start_idx: usize, // end of the fields. - fields_end_idx: usize, + event_fields_end_idx: usize, // end of everything (fields + topics) end_idx: usize, metadata: Metadata, @@ -221,10 +223,13 @@ impl EventDetails { let input = &mut &all_bytes[start_idx..]; let phase = Phase::decode(input)?; + + let event_start_idx = all_bytes.len() - input.len(); + let pallet_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: let event_metadata = metadata.event(pallet_index, variant_index)?; @@ -246,7 +251,7 @@ impl EventDetails { } // 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 // anything at the moment, so just decode and throw them away. @@ -259,8 +264,9 @@ impl EventDetails { phase, index, start_idx, - fields_start_idx, - fields_end_idx, + event_start_idx, + event_fields_start_idx, + event_fields_end_idx, end_idx, all_bytes, metadata, @@ -281,14 +287,14 @@ impl EventDetails { pub fn pallet_index(&self) -> u8 { // Note: never panics; we expect these bytes to exist // 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. pub fn variant_index(&self) -> u8 { // Note: never panics; we expect these bytes to exist // 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. @@ -319,7 +325,7 @@ impl EventDetails { /// Return the bytes representing the fields stored in this event. 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`] @@ -384,7 +390,7 @@ impl EventDetails { /// 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. pub fn as_root_event(&self) -> Result { - 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, events, events_raw, + AllEvents, }, *, }; @@ -572,6 +579,38 @@ mod tests { 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), + } + + // Create fake metadata that knows about our single event, above: + let metadata = metadata::(); + + // 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::( + metadata.clone(), + 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::>() + .expect("can decode event into root enum again"); + + // It should equal the event we put in: + assert_eq!(decoded_event, AllEvents::Test(event)); + } + #[test] fn dynamically_decode_single_event() { #[derive(Clone, Debug, PartialEq, Decode, Encode, TypeInfo)] From 8a0fb55323bf7e7976222fc7d6157e967f001f1f Mon Sep 17 00:00:00 2001 From: James Wilson Date: Tue, 10 Jan 2023 17:00:54 +0000 Subject: [PATCH 2/3] fmt and clippy --- subxt/src/events/events_type.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subxt/src/events/events_type.rs b/subxt/src/events/events_type.rs index 1680be4f61..cb80f889af 100644 --- a/subxt/src/events/events_type.rs +++ b/subxt/src/events/events_type.rs @@ -593,7 +593,7 @@ mod tests { // construst an Events object to iterate them: let event = Event::A(1, true, vec!["Hi".into()]); let events = events::( - metadata.clone(), + metadata, vec![event_record(Phase::ApplyExtrinsic(123), event.clone())], ); @@ -604,7 +604,8 @@ mod tests { .expect("event should be extracted OK"); // This is the line we're testing: - let decoded_event = ev.as_root_event::>() + let decoded_event = ev + .as_root_event::>() .expect("can decode event into root enum again"); // It should equal the event we put in: From 4354a3021b262b82bea1fb3ef76c63bb8113dfd4 Mon Sep 17 00:00:00 2001 From: James Wilson Date: Wed, 11 Jan 2023 10:34:47 +0000 Subject: [PATCH 3/3] Update subxt/src/events/events_type.rs Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> --- subxt/src/events/events_type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subxt/src/events/events_type.rs b/subxt/src/events/events_type.rs index cb80f889af..7efc7d93d4 100644 --- a/subxt/src/events/events_type.rs +++ b/subxt/src/events/events_type.rs @@ -203,7 +203,7 @@ pub struct EventDetails { start_idx: usize, // start of the event (ie pallet/variant index and then the fields and topic after). event_start_idx: usize, - // start of the fields (ie after phase nad pallet/variant index). + // start of the fields (ie after phase and pallet/variant index). event_fields_start_idx: usize, // end of the fields. event_fields_end_idx: usize,