1#[cfg(feature = "std")]
2use crate::utils::as_hex;
3#[cfg(feature = "std")]
4use serde::{Deserialize, Serialize};
5
6use frame_system::{EventRecord, Phase};
7use parity_scale_codec::{Codec, Decode, DecodeWithMemTracking, Encode, EncodeLike};
8use scale_info::TypeInfo;
9extern crate alloc;
10use alloc::vec::Vec;
11use core::fmt::Debug;
12
13#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
18#[derive(Debug, TypeInfo, Clone, Encode, Decode, PartialEq, Eq)]
19pub struct RpcEvent {
20 pub phase: Option<u32>,
23 pub pallet: u8,
25 pub event: u8,
27 #[cfg_attr(feature = "std", serde(with = "as_hex",))]
29 pub data: Vec<u8>,
30}
31
32impl<RuntimeEvent, Hash> From<EventRecord<RuntimeEvent, Hash>> for RpcEvent
33where
34 RuntimeEvent: DecodeWithMemTracking
35 + Codec
36 + Sync
37 + Send
38 + TypeInfo
39 + Debug
40 + Eq
41 + Clone
42 + EncodeLike
43 + 'static,
44{
45 fn from(event: EventRecord<RuntimeEvent, Hash>) -> Self {
46 let phase = match event.phase {
47 Phase::ApplyExtrinsic(i) => Some(i),
48 _ => None,
49 };
50
51 let full_encoding = Encode::encode(&event.event);
53 let pallet = full_encoding[0];
54 let event = full_encoding[1];
55 let data = &full_encoding[2..];
56
57 RpcEvent { phase, pallet, event, data: data.to_vec() }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[derive(Debug, TypeInfo, Clone, Encode, Decode, DecodeWithMemTracking, Eq, PartialEq)]
66 enum FakeRuntime {
67 #[codec(index = 60)]
68 FakePallet(FakePalletEvents),
69 }
70
71 #[derive(Debug, TypeInfo, Clone, Encode, Decode, DecodeWithMemTracking, Eq, PartialEq)]
72 enum FakePalletEvents {
73 #[codec(index = 7)]
74 FakeEvent { msa_id: u64 },
75 }
76
77 #[test]
78 fn rpc_event_from_event_record() {
79 let event: EventRecord<FakeRuntime, ()> = EventRecord {
80 phase: Phase::ApplyExtrinsic(5),
81 event: FakeRuntime::FakePallet(FakePalletEvents::FakeEvent { msa_id: 42 }),
82 topics: vec![],
83 };
84 let rpc_event: RpcEvent = event.into();
85 assert_eq!(
86 rpc_event,
87 RpcEvent { phase: Some(5), pallet: 60, event: 7, data: vec![42, 0, 0, 0, 0, 0, 0, 0] }
88 );
89 }
90
91 #[test]
92 fn rpc_event_from_event_record_with_different_phase() {
93 let event: EventRecord<FakeRuntime, ()> = EventRecord {
94 phase: Phase::Finalization,
95 event: FakeRuntime::FakePallet(FakePalletEvents::FakeEvent { msa_id: 42 }),
96 topics: vec![],
97 };
98 let rpc_event: RpcEvent = event.into();
99 assert_eq!(
100 rpc_event,
101 RpcEvent { phase: None, pallet: 60, event: 7, data: vec![42, 0, 0, 0, 0, 0, 0, 0] }
102 );
103 }
104}