etop_core/datasets/
transactions_by_to_address.rs

1use crate::{DataSpec, DataWarehouse, EtopError, InputDataset};
2use etop_format::{ColumnFormatShorthand, NumberFormat};
3use polars::prelude::*;
4use std::collections::HashMap;
5
6/// transactions by address
7#[derive(Clone)]
8pub struct TransactionsByToAddress;
9
10impl DataSpec for TransactionsByToAddress {
11    fn name(&self) -> String {
12        "transactions_by_to_address".into()
13    }
14
15    fn row_noun(&self) -> String {
16        "to_addresses".into()
17    }
18
19    fn inputs(&self) -> Vec<InputDataset> {
20        vec![InputDataset::Raw("transactions".into())]
21    }
22
23    fn transform(
24        &self,
25        inputs: &DataWarehouse,
26        start_block: Option<u32>,
27        end_block: Option<u32>,
28    ) -> Result<DataFrame, EtopError> {
29        let txs = inputs.get_dataset("transactions")?;
30        let txs = crate::filter_by_block_number(txs, start_block, end_block)?;
31        txs.clone()
32            .lazy()
33            .group_by(["to_address"])
34            .agg([
35                count().alias("n_txs"),
36                col("value_f64").sum().alias("eth_sent") / lit(1e18),
37                col("gas_price").mean().alias("mean_gas_price") / lit(1e9),
38                col("gas_used").mean().alias("mean_gas_used"),
39            ])
40            .sort_by_exprs(vec![col("n_txs"), col("to_address")], [true, true], true, false)
41            .collect()
42            .map_err(EtopError::PolarsError)
43    }
44
45    fn default_columns(&self) -> Option<Vec<String>> {
46        let columns = ["to_address", "n_txs", "eth_sent", "mean_gas_price", "mean_gas_used"]
47            .iter()
48            .map(|s| s.to_string())
49            .collect();
50        Some(columns)
51    }
52
53    fn default_column_formats(&self) -> Option<HashMap<String, ColumnFormatShorthand>> {
54        let float_format = NumberFormat::new().si().precision(3);
55        let oom_integer_format = NumberFormat::new().integer_oom().precision(0);
56        let oom_float_format = NumberFormat::new().float_oom().precision(1);
57        let formats = vec![
58            ColumnFormatShorthand::new().name("to_address").newline_underscores(),
59            ColumnFormatShorthand::new()
60                .name("n_txs")
61                .newline_underscores()
62                .set_format(oom_integer_format.clone())
63                .min_width(4),
64            ColumnFormatShorthand::new()
65                .name("eth_sent")
66                .newline_underscores()
67                .set_format(oom_float_format.clone())
68                .min_width(6),
69            ColumnFormatShorthand::new()
70                .name("mean_gas_price")
71                .newline_underscores()
72                .set_format(float_format),
73            ColumnFormatShorthand::new()
74                .name("mean_gas_used")
75                .newline_underscores()
76                .set_format(oom_float_format.clone())
77                .min_width(6),
78        ]
79        .into_iter()
80        .map(|column| (column.name.clone(), column))
81        .collect();
82
83        Some(formats)
84    }
85}