1use std::borrow::Cow;
4
5use crate::eth::primitives::Address;
6use crate::infra::metrics;
7
8include!(concat!(env!("OUT_DIR"), "/contracts.rs"));
9include!(concat!(env!("OUT_DIR"), "/signatures.rs"));
10
11pub type SoliditySignature = &'static str;
12
13pub type ContractName = &'static str;
14
15pub fn contract_name(address: &Option<Address>) -> ContractName {
17 let Some(address) = address else { return metrics::LABEL_MISSING };
18 match CONTRACTS.get(address.as_slice()) {
19 Some(contract_name) => contract_name,
20 None => metrics::LABEL_UNKNOWN,
21 }
22}
23
24pub fn function_sig(bytes: impl AsRef<[u8]>) -> SoliditySignature {
26 match function_sig_opt(bytes) {
27 Some(signature) => signature,
28 None => metrics::LABEL_UNKNOWN,
29 }
30}
31
32pub fn function_sig_opt(bytes: impl AsRef<[u8]>) -> Option<SoliditySignature> {
34 let Some(id) = bytes.as_ref().get(..4) else {
35 return Some(metrics::LABEL_MISSING);
36 };
37 SIGNATURES_4_BYTES.get(id).copied()
38}
39
40pub fn error_sig_opt(bytes: impl AsRef<[u8]>) -> Option<Cow<'static, str>> {
42 bytes
43 .as_ref()
44 .get(..4)
45 .and_then(|id| SIGNATURES_4_BYTES.get(id))
46 .copied()
47 .map(Cow::Borrowed)
48 .or_else(|| {
49 bytes.as_ref().get(4..).and_then(|bytes| {
50 ethabi::decode(&[ethabi::ParamType::String], bytes)
51 .ok()
52 .and_then(|res| res.first().cloned())
53 .and_then(|token| token.into_string())
54 .map(Cow::Owned)
55 })
56 })
57}