1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::{
api::{
config::GearConfig,
generated::api::{
gear::Event as GearEvent, system::Event as SystemEvent, DispatchError, Event,
},
Api,
},
result::Result,
};
use futures_util::StreamExt;
use subxt::{
codec::Decode,
events::EventSubscription,
rpc::Subscription,
sp_runtime::{generic::Header, traits::BlakeTwo256},
HasModuleError, ModuleError, RuntimeError, TransactionEvents, TransactionInBlock,
};
pub type Events<'a> =
EventSubscription<'a, Subscription<Header<u32, BlakeTwo256>>, GearConfig, Event>;
#[allow(unused)]
pub type InBlockEvents = TransactionEvents<GearConfig, Event>;
impl Api {
#[allow(unused)]
pub async fn events(&self) -> Result<Events<'_>> {
Ok(self.0.events().subscribe().await?)
}
pub async fn capture_dispatch_info<'e>(
&'e self,
tx: &TransactionInBlock<'e, GearConfig, DispatchError, Event>,
) -> Result<InBlockEvents> {
let events = tx.fetch_events().await?;
for (raw, event) in events.iter_raw().zip(events.iter()) {
let ev = raw?;
if &ev.pallet == "System" && &ev.variant == "ExtrinsicFailed" {
Self::capture_weight_info(event?.event);
let dispatch_error = DispatchError::decode(&mut &*ev.data)?;
if let Some(error_data) = dispatch_error.module_error_data() {
let locked_metadata = self.0.client.metadata();
let metadata = locked_metadata.read();
let details =
metadata.error(error_data.pallet_index, error_data.error_index())?;
return Err(subxt::Error::Module(ModuleError {
pallet: details.pallet().to_string(),
error: details.error().to_string(),
description: details.description().to_vec(),
error_data,
})
.into());
} else {
return Err(subxt::Error::Runtime(RuntimeError(dispatch_error)).into());
}
} else if &ev.pallet == "System" && &ev.variant == "ExtrinsicSuccess" {
Self::capture_weight_info(event?.event);
break;
}
}
Ok(events)
}
pub fn capture_weight_info(event: Event) {
if let Event::System(SystemEvent::ExtrinsicSuccess { dispatch_info })
| Event::System(SystemEvent::ExtrinsicFailed { dispatch_info, .. }) = event
{
log::info!("\tWeight cost: {:?}", dispatch_info.weight);
}
}
pub async fn wait_for(mut events: Events<'_>, wait: fn(GearEvent) -> bool) -> Result<()> {
while let Some(events) = events.next().await {
for maybe_event in events?.iter() {
let event = maybe_event?.event;
if let Event::System(SystemEvent::ExtrinsicFailed { .. }) = event {
return Ok(());
}
if let Event::Gear(e) = event {
log::info!("\t{e:?}");
if wait(e) {
return Ok(());
}
}
}
}
Ok(())
}
}