Skip to content

Commit

Permalink
Added export stats
Browse files Browse the repository at this point in the history
  • Loading branch information
scx1332 committed Oct 22, 2023
1 parent 03178f7 commit a8f368b
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
14 changes: 14 additions & 0 deletions crates/erc20_payment_lib/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ pub fn u256_to_eth(amount: U256) -> Result<Decimal, ConversionError> {
u256_to_rust_dec(amount, Some(18))
}

pub fn u256_eth_from_str(val: &str) -> Result<(U256, Decimal), ConversionError> {
let u256 = U256::from_dec_str(val)
.map_err(|err| ConversionError::from(format!("Invalid string when converting: {err:?}")))?;
let eth = u256_to_eth(u256)?;
Ok((u256, eth))
}

pub fn u256_gwei_from_str(val: &str) -> Result<(U256, Decimal), ConversionError> {
let u256 = U256::from_dec_str(val)
.map_err(|err| ConversionError::from(format!("Invalid string when converting: {err:?}")))?;
let gwei = u256_to_gwei(u256)?;
Ok((u256, gwei))
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
5 changes: 4 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use erc20_payment_lib::{
use std::env;
use std::str::FromStr;

use crate::stats::run_stats;
use crate::stats::{export_stats, run_stats};
use erc20_payment_lib::runtime::remove_last_unsent_transactions;
use erc20_payment_lib::service::transaction_from_chain_and_into_db;
use erc20_payment_lib::setup::PaymentSetup;
Expand Down Expand Up @@ -278,6 +278,9 @@ async fn main_internal() -> Result<(), PaymentError> {
generate_test_payments(generate_options, &config, public_addrs, Some(conn.clone()))
.await?;
}
PaymentCommands::ExportHistory {
export_history_stats_options,
} => export_stats(conn.clone(), export_history_stats_options, &config).await?,
PaymentCommands::PaymentStats {
payment_stats_options,
} => run_stats(conn.clone(), payment_stats_options, &config).await?,
Expand Down
11 changes: 11 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ pub struct ScanBlockchainOptions {
pub sender: String,
}

#[derive(StructOpt)]
#[structopt(about = "Export history stats")]
pub struct ExportHistoryStatsOptions {
#[structopt(short = "c", long = "chain-name", default_value = "polygon")]
pub chain_name: String,
}

#[derive(StructOpt)]
#[structopt(about = "Payment statistics options")]
pub struct PaymentStatsOptions {
Expand Down Expand Up @@ -235,6 +242,10 @@ pub enum PaymentCommands {
#[structopt(flatten)]
payment_stats_options: PaymentStatsOptions,
},
ExportHistory {
#[structopt(flatten)]
export_history_stats_options: ExportHistoryStatsOptions,
},
DecryptKeyStore {
#[structopt(flatten)]
decrypt_options: DecryptKeyStoreOptions,
Expand Down
67 changes: 64 additions & 3 deletions src/stats.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,76 @@
use chrono::{DateTime, NaiveDateTime, TimeZone};
use csv::WriterBuilder;
use erc20_payment_lib::config::Config;
use erc20_payment_lib::db::ops::{
get_transfer_stats, get_transfer_stats_from_blockchain, TransferStatsPart,
get_all_chain_transfers, get_chain_transfers_by_chain_id, get_transfer_stats,
get_transfer_stats_from_blockchain, TransferStatsPart,
};
use erc20_payment_lib::err_custom_create;
use itertools::{sorted, Itertools};
use rust_decimal::Decimal;
use sqlx::SqlitePool;
use std::fs;
use std::str::FromStr;
use std::time::{SystemTime, UNIX_EPOCH};
use web3::types::{H160, U256};

use crate::options::PaymentStatsOptions;
use crate::options::{ExportHistoryStatsOptions, PaymentStatsOptions};
use erc20_payment_lib::error::PaymentError;
use erc20_payment_lib::utils::u256_to_rust_dec;
use erc20_payment_lib::utils::{u256_eth_from_str, u256_to_rust_dec};

pub async fn export_stats(
conn: SqlitePool,
payment_stats_options: ExportHistoryStatsOptions,
config: &Config,
) -> Result<(), PaymentError> {
let chain_cfg =
config
.chain
.get(&payment_stats_options.chain_name)
.ok_or(err_custom_create!(
"Chain {} not found in config file",
payment_stats_options.chain_name
))?;

let mut writer = WriterBuilder::new()
.delimiter(b';')
.from_writer(std::fs::File::create("export.csv").unwrap());

let tchains = get_chain_transfers_by_chain_id(&conn, chain_cfg.chain_id, None)
.await
.unwrap();

let tchains = tchains
.into_iter()
.sorted_by_key(|t| t.blockchain_date.unwrap())
.collect_vec();

writer
.write_record(["time", "fee_paid", "fee_paid_total"])
.unwrap();
let mut fee_paid_total = Decimal::default();
for chain in tchains {
let Some(blockchain_date) = chain.blockchain_date else {
log::warn!("No blockchain date for transfer {}", chain.id);
continue;
};
let Some(fee_paid) = chain.fee_paid else {
log::warn!("No fee paid for transfer {}", chain.id);
continue;
};

let (_, fee_paid) = u256_eth_from_str(&fee_paid).unwrap();
fee_paid_total += fee_paid;
writer
.write_record([
blockchain_date.format("%Y-%m-%dT%H:%M:%S%.3f").to_string(),
format!("{:.6}", fee_paid),
format!("{:.6}", fee_paid_total),
])
.unwrap();
}
Ok(())
}

pub async fn run_stats(
conn: SqlitePool,
Expand Down

0 comments on commit a8f368b

Please sign in to comment.