nyxd_scraper_shared/
helpers.rs

1// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::block_processor::types::ParsedTransactionResponse;
5use crate::constants::{BECH32_CONESNSUS_PUBKEY_PREFIX, BECH32_CONSENSUS_ADDRESS_PREFIX};
6use cosmrs::AccountId;
7use sha2::{Digest, Sha256};
8use tendermint::{Hash, validator};
9use tendermint::{PublicKey, account};
10use tendermint_rpc::endpoint::validators;
11use thiserror::Error;
12
13#[derive(Error, Debug)]
14pub enum MalformedDataError {
15    #[error("failed to parse validator's address: {source}")]
16    MalformedValidatorAddress {
17        #[source]
18        source: eyre::Report,
19    },
20
21    #[error("failed to parse validator's address: {source}")]
22    MalformedValidatorPubkey {
23        #[source]
24        source: eyre::Report,
25    },
26
27    #[error(
28        "could not find validator information for {address}; the validator has signed a commit"
29    )]
30    MissingValidatorInfoCommitted { address: String },
31}
32
33pub fn tx_hash<M: AsRef<[u8]>>(raw_tx: M) -> Hash {
34    Hash::Sha256(Sha256::digest(raw_tx).into())
35}
36
37pub fn validator_pubkey_to_bech32(pubkey: PublicKey) -> Result<AccountId, MalformedDataError> {
38    // TODO: this one seem to attach additional prefix to they pubkeys, is that what we want instead maybe?
39    // Ok(pubkey.to_bech32(BECH32_CONESNSUS_PUBKEY_PREFIX))
40    AccountId::new(BECH32_CONESNSUS_PUBKEY_PREFIX, &pubkey.to_bytes())
41        .map_err(|source| MalformedDataError::MalformedValidatorPubkey { source })
42}
43
44pub fn validator_consensus_address(id: account::Id) -> Result<AccountId, MalformedDataError> {
45    AccountId::new(BECH32_CONSENSUS_ADDRESS_PREFIX, id.as_ref())
46        .map_err(|source| MalformedDataError::MalformedValidatorAddress { source })
47}
48
49pub fn tx_gas_sum(txs: &[ParsedTransactionResponse]) -> i64 {
50    txs.iter().map(|tx| tx.tx_result.gas_used).sum()
51}
52
53pub fn validator_info(
54    id: account::Id,
55    validators: &validators::Response,
56) -> Result<&validator::Info, MalformedDataError> {
57    match validators.validators.iter().find(|v| v.address == id) {
58        Some(info) => Ok(info),
59        None => {
60            let addr = validator_consensus_address(id)?;
61            Err(MalformedDataError::MissingValidatorInfoCommitted {
62                address: addr.to_string(),
63            })
64        }
65    }
66}