etop_core/datasets/
blocks.rs1use crate::{DataSpec, DataWarehouse, EtopError, InputDataset};
2use etop_format::ColumnFormatShorthand;
3use polars::prelude::*;
4use std::collections::HashMap;
5
6#[derive(Clone)]
8pub struct Blocks;
9
10impl DataSpec for Blocks {
11 fn name(&self) -> String {
12 "blocks".to_string()
13 }
14
15 fn row_noun(&self) -> String {
16 "blocks".to_string()
17 }
18
19 fn inputs(&self) -> Vec<InputDataset> {
20 vec![InputDataset::Raw("blocks".into()), InputDataset::Raw("transactions".into())]
21 }
22
23 fn transform(
24 &self,
25 warehouse: &DataWarehouse,
26 start_block: Option<u32>,
27 end_block: Option<u32>,
28 ) -> Result<DataFrame, EtopError> {
29 let sort = SortOptions {
30 descending: true,
31 nulls_last: true,
32 multithreaded: true,
33 maintain_order: true,
34 };
35 let join_args = JoinArgs {
36 how: JoinType::Left,
37 validation: JoinValidation::ManyToMany,
38 suffix: None,
39 slice: None,
40 };
41
42 let txs = warehouse
43 .get_dataset("transactions")?
44 .clone()
45 .lazy()
46 .group_by(["block_number"])
47 .agg([count().alias("n_txs")])
48 .collect()?;
49 let blocks = warehouse
50 .get_dataset("blocks")?
51 .clone()
52 .lazy()
53 .with_column(col("base_fee_per_gas") / lit(1e9))
54 .sort("block_number", sort)
55 .collect()
56 .map_err(EtopError::PolarsError)?;
57
58 let blocks = crate::filter_by_block_number(blocks, start_block, end_block)?;
59
60 blocks
61 .clone()
62 .lazy()
63 .join(txs.lazy(), [col("block_number")], [col("block_number")], join_args)
64 .collect()
65 .map_err(EtopError::PolarsError)
66 }
67
68 fn default_columns(&self) -> Option<Vec<String>> {
69 let columns =
70 ["block_number", "timestamp", "n_txs", "gas_used", "base_fee_per_gas", "author"]
71 .iter()
72 .map(|s| s.to_string())
73 .collect();
74 Some(columns)
75 }
76
77 fn default_column_formats(&self) -> Option<HashMap<String, ColumnFormatShorthand>> {
78 let integer_oom = etop_format::NumberFormat::new().integer_oom().precision(1);
79 let float_oom = etop_format::NumberFormat::new().float_oom().precision(1);
80 let timestamp_fmt = etop_format::NumberFormat::new().timestamp();
81
82 let formats = vec![
83 ColumnFormatShorthand::new().name("block_number").newline_underscores(),
84 ColumnFormatShorthand::new().name("timestamp").set_format(timestamp_fmt),
85 ColumnFormatShorthand::new().name("n_txs").set_format(integer_oom.clone()),
86 ColumnFormatShorthand::new()
87 .name("gas_used")
88 .set_format(integer_oom)
89 .min_width(5)
90 .newline_underscores(),
91 ColumnFormatShorthand::new()
92 .name("base_fee_per_gas")
93 .display_name("base_fee")
94 .set_format(float_oom)
95 .min_width(5)
96 .newline_underscores(),
97 ColumnFormatShorthand::new().name("author"),
98 ]
99 .into_iter()
100 .map(|column| (column.name.clone(), column))
101 .collect();
102
103 Some(formats)
104 }
105}