avail_rust_core/
decoded_events.rs

1use codec::{Decode, Encode};
2use serde::{Deserialize, Serialize};
3
4pub trait HasEventEmittedIndex {
5	// Pallet ID, Variant ID
6	const EMITTED_INDEX: (u8, u8);
7}
8
9pub trait TransactionEventEncodable {
10	/// SCALE encodes the event
11	///
12	/// If you need to Hex and SCALE encode then call `encode_as_hex_event`
13	fn encode_as_event(&self) -> Vec<u8>;
14
15	/// Hex and SCALE encodes the event
16	///
17	/// If you need to just SCALE encode then call `encode_as_event`
18	fn encode_as_hex_event(&self) -> String;
19}
20
21pub trait TransactionEventDecodable {
22	/// Decodes the SCALE encoded Event
23	///
24	/// If you need to decode Hex string call `decode_hex_event`
25	fn decode_event(event: &[u8]) -> Option<Box<Self>>;
26
27	/// Decodes the Hex and SCALE encoded Transaction Call
28	/// This is equal to Hex::decode + Self::decode_event
29	///
30	/// If you need to decode bytes call `decode_event`
31	fn decode_hex_event(event: &str) -> Option<Box<Self>>;
32
33	/// Decodes the SCALE encoded Event Data
34	fn decode_event_data(event_data: &[u8]) -> Option<Box<Self>>;
35}
36
37impl<T: HasEventEmittedIndex + Encode> TransactionEventEncodable for T {
38	fn encode_as_event(&self) -> Vec<u8> {
39		let pallet_id = Self::EMITTED_INDEX.0;
40		let variant_id = Self::EMITTED_INDEX.1;
41		let mut encoded_event: Vec<u8> = vec![pallet_id, variant_id];
42		Self::encode_to(self, &mut encoded_event);
43
44		encoded_event
45	}
46
47	fn encode_as_hex_event(&self) -> String {
48		std::format!("0x{}", const_hex::encode(Self::encode_as_event(self)))
49	}
50}
51
52impl<T: HasEventEmittedIndex + Decode> TransactionEventDecodable for T {
53	fn decode_event(event: &[u8]) -> Option<Box<T>> {
54		// This was moved out in order to decrease compilation times
55		if !event_filter_in(event, Self::EMITTED_INDEX) {
56			return None;
57		}
58
59		if event.len() <= 2 {
60			try_decode_event_data(&[])
61		} else {
62			try_decode_event_data(&event[2..])
63		}
64	}
65
66	#[inline(always)]
67	fn decode_hex_event(event: &str) -> Option<Box<T>> {
68		let hex_decoded = const_hex::decode(event.trim_start_matches("0x")).ok()?;
69		Self::decode_event(&hex_decoded)
70	}
71
72	fn decode_event_data(event_data: &[u8]) -> Option<Box<T>> {
73		// This was moved out in order to decrease compilation times
74		try_decode_event_data(event_data)
75	}
76}
77
78// Purely here to decrease compilation times
79#[inline(never)]
80fn try_decode_event_data<T: Decode>(mut event_data: &[u8]) -> Option<Box<T>> {
81	T::decode(&mut event_data).ok().map(Box::new)
82}
83
84// Purely here to decrease compilation times
85#[inline(never)]
86fn event_filter_in(event: &[u8], emitted_index: (u8, u8)) -> bool {
87	if event.len() < 2 {
88		return false;
89	}
90
91	let (pallet_id, variant_id) = (event[0], event[1]);
92	if emitted_index.0 != pallet_id || emitted_index.1 != variant_id {
93		return false;
94	}
95
96	true
97}
98
99/// Contains only the event body. Phase and topics are not included here.
100#[derive(Debug, Clone)]
101pub struct OpaqueEvent(pub Vec<u8>);
102
103impl OpaqueEvent {
104	pub fn pallet_index(&self) -> u8 {
105		self.0[0]
106	}
107
108	pub fn variant_index(&self) -> u8 {
109		self.0[1]
110	}
111
112	pub fn event_data(&self) -> &[u8] {
113		if self.0.len() <= 2 { &[] } else { &self.0[2..] }
114	}
115}
116
117impl TryFrom<String> for OpaqueEvent {
118	type Error = String;
119
120	fn try_from(value: String) -> Result<Self, Self::Error> {
121		Self::try_from(value.as_str())
122	}
123}
124
125impl TryFrom<&String> for OpaqueEvent {
126	type Error = String;
127
128	fn try_from(value: &String) -> Result<Self, Self::Error> {
129		Self::try_from(value.as_str())
130	}
131}
132
133impl TryFrom<&str> for OpaqueEvent {
134	type Error = String;
135
136	fn try_from(value: &str) -> Result<Self, Self::Error> {
137		let value = const_hex::decode(value).map_err(|x| x.to_string())?;
138		Self::try_from(value)
139	}
140}
141
142impl TryFrom<Vec<u8>> for OpaqueEvent {
143	type Error = String;
144
145	fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
146		Self::try_from(value.as_slice())
147	}
148}
149
150impl TryFrom<&Vec<u8>> for OpaqueEvent {
151	type Error = String;
152
153	fn try_from(value: &Vec<u8>) -> Result<Self, Self::Error> {
154		Self::try_from(value.as_slice())
155	}
156}
157
158impl TryFrom<&[u8]> for OpaqueEvent {
159	type Error = String;
160
161	fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
162		if value.len() < 2 {
163			return Err("Event must have more than one byte".into());
164		}
165
166		Ok(OpaqueEvent(value.to_owned()))
167	}
168}
169
170/// A phase of a block's execution.
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)]
172pub enum RuntimePhase {
173	/// Applying an extrinsic.
174	ApplyExtrinsic(u32),
175	/// Finalizing the block.
176	Finalization,
177	/// Initializing the block.
178	Initialization,
179}