ibc_telemetry/
broadcast_error.rs

1//! The BroadcastError is used by the telemetry in order to correctly batch
2//! together the error reports from ibc-go or Cosmos SDK.
3//! When a broadcast error is received by Hermes it will contain a code and
4//! a description, but the code description depends on the source of the error.
5//! For example Cosmos SDK error code 13 is "insufficient fee", and error
6//! code 13 for Ibc Go is "invalid packet".
7//! The description might contain some variables for example error 32 would be:
8//! "account sequence mismatch, expected 1234, got 1235: incorrect account sequence"
9//! The BroadcastError will reduce the description to simple: "incorrect account sequence"
10//!
11//! Cosmos SDK errors: <https://github.com/cosmos/cosmos-sdk/blob/v0.50.1/types/errors/errors.go>
12//! Ibc Go errors: <https://github.com/cosmos/ibc-go/blob/v8.0.0/modules/core/04-channel/types/errors.go>
13
14pub struct BroadcastError {
15    pub code: u32,
16    pub description: String,
17}
18
19impl BroadcastError {
20    pub fn new(code: u32, description: &str) -> Self {
21        let short_description = get_short_description(code, description);
22        Self {
23            code,
24            description: short_description,
25        }
26    }
27}
28
29fn get_short_description(code: u32, description: &str) -> String {
30    match code {
31        2 => {
32            let sdk_error = "tx parse error";
33            let ibc_go_error = "channel already exists";
34            if description.contains(sdk_error) {
35                Some(sdk_error.to_owned())
36            } else if description.contains(ibc_go_error) {
37                Some(ibc_go_error.to_owned())
38            } else {
39                None
40            }
41        }
42        3 => {
43            let sdk_error = "invalid sequence";
44            let ibc_go_error = "channel not found";
45            if description.contains(sdk_error) {
46                Some(sdk_error.to_owned())
47            } else if description.contains(ibc_go_error) {
48                Some(ibc_go_error.to_owned())
49            } else {
50                None
51            }
52        }
53        4 => {
54            let sdk_error = "unauthorized";
55            let ibc_go_error = "invalid channel";
56            if description.contains(sdk_error) {
57                Some(sdk_error.to_owned())
58            } else if description.contains(ibc_go_error) {
59                Some(ibc_go_error.to_owned())
60            } else {
61                None
62            }
63        }
64        5 => {
65            let sdk_error = "insufficient funds";
66            let ibc_go_error = "invalid channel state";
67            if description.contains(sdk_error) {
68                Some(sdk_error.to_owned())
69            } else if description.contains(ibc_go_error) {
70                Some(ibc_go_error.to_owned())
71            } else {
72                None
73            }
74        }
75        6 => {
76            let sdk_error = "unknown request";
77            let ibc_go_error = "invalid channel ordering";
78            if description.contains(sdk_error) {
79                Some(sdk_error.to_owned())
80            } else if description.contains(ibc_go_error) {
81                Some(ibc_go_error.to_owned())
82            } else {
83                None
84            }
85        }
86        7 => {
87            let sdk_error = "invalid address";
88            let ibc_go_error = "invalid counterparty channel";
89            if description.contains(sdk_error) {
90                Some(sdk_error.to_owned())
91            } else if description.contains(ibc_go_error) {
92                Some(ibc_go_error.to_owned())
93            } else {
94                None
95            }
96        }
97        8 => {
98            let sdk_error = "invalid pubkey";
99            let ibc_go_error = "invalid channel capability";
100            if description.contains(sdk_error) {
101                Some(sdk_error.to_owned())
102            } else if description.contains(ibc_go_error) {
103                Some(ibc_go_error.to_owned())
104            } else {
105                None
106            }
107        }
108        9 => {
109            let sdk_error = "unknown address";
110            let ibc_go_error = "channel capability not found";
111            if description.contains(sdk_error) {
112                Some(sdk_error.to_owned())
113            } else if description.contains(ibc_go_error) {
114                Some(ibc_go_error.to_owned())
115            } else {
116                None
117            }
118        }
119        10 => {
120            let sdk_error = "invalid coins";
121            let ibc_go_error = "sequence send not found";
122            if description.contains(sdk_error) {
123                Some(sdk_error.to_owned())
124            } else if description.contains(ibc_go_error) {
125                Some(ibc_go_error.to_owned())
126            } else {
127                None
128            }
129        }
130        11 => {
131            let sdk_error = "out of gas";
132            let ibc_go_error = "sequence receive not found";
133            if description.contains(sdk_error) {
134                Some(sdk_error.to_owned())
135            } else if description.contains(ibc_go_error) {
136                Some(ibc_go_error.to_owned())
137            } else {
138                None
139            }
140        }
141        12 => {
142            let sdk_error = "memo too large";
143            let ibc_go_error = "sequence acknowledgement not found";
144            if description.contains(sdk_error) {
145                Some(sdk_error.to_owned())
146            } else if description.contains(ibc_go_error) {
147                Some(ibc_go_error.to_owned())
148            } else {
149                None
150            }
151        }
152        13 => {
153            let sdk_error = "insufficient fee";
154            let ibc_go_error = "invalid packet";
155            if description.contains(sdk_error) {
156                Some(sdk_error.to_owned())
157            } else if description.contains(ibc_go_error) {
158                Some(ibc_go_error.to_owned())
159            } else {
160                None
161            }
162        }
163        14 => {
164            let sdk_error = "maximum number of signatures exceeded";
165            let ibc_go_error = "packet timeout";
166            if description.contains(sdk_error) {
167                Some(sdk_error.to_owned())
168            } else if description.contains(ibc_go_error) {
169                Some(ibc_go_error.to_owned())
170            } else {
171                None
172            }
173        }
174        15 => {
175            let sdk_error = "no signatures supplied";
176            let ibc_go_error = "too many connection hops";
177            if description.contains(sdk_error) {
178                Some(sdk_error.to_owned())
179            } else if description.contains(ibc_go_error) {
180                Some(ibc_go_error.to_owned())
181            } else {
182                None
183            }
184        }
185        16 => {
186            let sdk_error = "failed to marshal JSON bytes";
187            let ibc_go_error = "invalid acknowledgement";
188            if description.contains(sdk_error) {
189                Some(sdk_error.to_owned())
190            } else if description.contains(ibc_go_error) {
191                Some(ibc_go_error.to_owned())
192            } else {
193                None
194            }
195        }
196        17 => {
197            let sdk_error = "failed to unmarshal JSON bytes";
198            let ibc_go_error = "acknowledgement for packet already exists";
199            if description.contains(sdk_error) {
200                Some(sdk_error.to_owned())
201            } else if description.contains(ibc_go_error) {
202                Some(ibc_go_error.to_owned())
203            } else {
204                None
205            }
206        }
207        18 => {
208            let sdk_error = "invalid request";
209            let ibc_go_error = "invalid channel identifier";
210            if description.contains(sdk_error) {
211                Some(sdk_error.to_owned())
212            } else if description.contains(ibc_go_error) {
213                Some(ibc_go_error.to_owned())
214            } else {
215                None
216            }
217        }
218        19 => {
219            let sdk_error = "tx already in mempool";
220            let ibc_go_error = "packet already received";
221            if description.contains(sdk_error) {
222                Some(sdk_error.to_owned())
223            } else if description.contains(ibc_go_error) {
224                Some(ibc_go_error.to_owned())
225            } else {
226                None
227            }
228        }
229        20 => {
230            let sdk_error = "mempool is full";
231            let ibc_go_error = "packet commitment not found";
232            if description.contains(sdk_error) {
233                Some(sdk_error.to_owned())
234            } else if description.contains(ibc_go_error) {
235                Some(ibc_go_error.to_owned())
236            } else {
237                None
238            }
239        }
240        21 => {
241            let sdk_error = "tx too large";
242            let ibc_go_error = "packet sequence is out of order";
243            if description.contains(sdk_error) {
244                Some(sdk_error.to_owned())
245            } else if description.contains(ibc_go_error) {
246                Some(ibc_go_error.to_owned())
247            } else {
248                None
249            }
250        }
251        22 => {
252            let sdk_error = "key not found";
253            let ibc_go_error = "packet messages are redundant";
254            if description.contains(sdk_error) {
255                Some(sdk_error.to_owned())
256            } else if description.contains(ibc_go_error) {
257                Some(ibc_go_error.to_owned())
258            } else {
259                None
260            }
261        }
262        23 => {
263            let sdk_error = "invalid account password";
264            let ibc_go_error = "message is redundant, no-op will be performed";
265            if description.contains(sdk_error) {
266                Some(sdk_error.to_owned())
267            } else if description.contains(ibc_go_error) {
268                Some(ibc_go_error.to_owned())
269            } else {
270                None
271            }
272        }
273        24 => {
274            let sdk_error = "tx intended signer does not match the given signer";
275            let ibc_go_error = "invalid channel version";
276            if description.contains(sdk_error) {
277                Some(sdk_error.to_owned())
278            } else if description.contains(ibc_go_error) {
279                Some(ibc_go_error.to_owned())
280            } else {
281                None
282            }
283        }
284        25 => {
285            let sdk_error = "invalid gas adjustment";
286            let ibc_go_error = "packet has not been sent";
287            if description.contains(sdk_error) {
288                Some(sdk_error.to_owned())
289            } else if description.contains(ibc_go_error) {
290                Some(ibc_go_error.to_owned())
291            } else {
292                None
293            }
294        }
295        26 => {
296            let sdk_error = "invalid height";
297            let ibc_go_error = "invalid packet timeout";
298            if description.contains(sdk_error) {
299                Some(sdk_error.to_owned())
300            } else if description.contains(ibc_go_error) {
301                Some(ibc_go_error.to_owned())
302            } else {
303                None
304            }
305        }
306        27 => {
307            let sdk_error = "invalid version";
308            if description.contains(sdk_error) {
309                Some(sdk_error.to_owned())
310            } else {
311                None
312            }
313        }
314        28 => {
315            let sdk_error = "invalid chain-id";
316            if description.contains(sdk_error) {
317                Some(sdk_error.to_owned())
318            } else {
319                None
320            }
321        }
322        29 => {
323            let sdk_error = "invalid type";
324            if description.contains(sdk_error) {
325                Some(sdk_error.to_owned())
326            } else {
327                None
328            }
329        }
330        30 => {
331            let sdk_error = "tx timeout height";
332            if description.contains(sdk_error) {
333                Some(sdk_error.to_owned())
334            } else {
335                None
336            }
337        }
338        31 => {
339            let sdk_error = "unknown extension options";
340            if description.contains(sdk_error) {
341                Some(sdk_error.to_owned())
342            } else {
343                None
344            }
345        }
346        32 => {
347            let sdk_error = "incorrect account sequence";
348            if description.contains(sdk_error) {
349                Some(sdk_error.to_owned())
350            } else {
351                None
352            }
353        }
354        33 => {
355            let sdk_error = "failed packing protobuf message to Any";
356            if description.contains(sdk_error) {
357                Some(sdk_error.to_owned())
358            } else {
359                None
360            }
361        }
362        34 => {
363            let sdk_error = "failed unpacking protobuf message from Any";
364            if description.contains(sdk_error) {
365                Some(sdk_error.to_owned())
366            } else {
367                None
368            }
369        }
370        35 => {
371            let sdk_error = "internal logic error";
372            if description.contains(sdk_error) {
373                Some(sdk_error.to_owned())
374            } else {
375                None
376            }
377        }
378        36 => {
379            let sdk_error = "conflict";
380            if description.contains(sdk_error) {
381                Some(sdk_error.to_owned())
382            } else {
383                None
384            }
385        }
386        37 => {
387            let sdk_error = "feature not supported";
388            if description.contains(sdk_error) {
389                Some(sdk_error.to_owned())
390            } else {
391                None
392            }
393        }
394        38 => {
395            let sdk_error = "not found";
396            if description.contains(sdk_error) {
397                Some(sdk_error.to_owned())
398            } else {
399                None
400            }
401        }
402        39 => {
403            let sdk_error = "Internal IO error";
404            if description.contains(sdk_error) {
405                Some(sdk_error.to_owned())
406            } else {
407                None
408            }
409        }
410        40 => {
411            let sdk_error = "error in app.toml";
412            if description.contains(sdk_error) {
413                Some(sdk_error.to_owned())
414            } else {
415                None
416            }
417        }
418        41 => {
419            let sdk_error = "invalid gas limit";
420            if description.contains(sdk_error) {
421                Some(sdk_error.to_owned())
422            } else {
423                None
424            }
425        }
426        _ => None,
427    }
428    .unwrap_or_else(|| "unknown error".to_owned())
429}