use std::time::{Instant, Duration};
use ansi_term::Colour;
use vapory_types::U256;
use tetsy_runtime::Executor;
use price_info::{Client as PriceInfoClient, PriceInfo};
use price_info::tetsy_fetch::Client as FetchClient;
#[derive(Debug, PartialEq)]
pub struct GasPriceCalibratorOptions {
pub usd_per_tx: f32,
pub recalibration_period: Duration,
}
#[derive(Debug, PartialEq)]
pub struct GasPriceCalibrator {
options: GasPriceCalibratorOptions,
next_calibration: Instant,
price_info: PriceInfoClient,
}
impl GasPriceCalibrator {
pub fn new(options: GasPriceCalibratorOptions, fetch: FetchClient, p: Executor, api_endpoint: String) -> GasPriceCalibrator {
GasPriceCalibrator {
options: options,
next_calibration: Instant::now(),
price_info: PriceInfoClient::new(fetch, p, api_endpoint),
}
}
pub(crate) fn recalibrate<F: FnOnce(U256) + Sync + Send + 'static>(&mut self, set_price: F) {
trace!(target: "miner", "Recalibrating {:?} versus {:?}", Instant::now(), self.next_calibration);
if Instant::now() >= self.next_calibration {
let usd_per_tx = self.options.usd_per_tx;
trace!(target: "miner", "Getting price info");
self.price_info.get(move |price: PriceInfo| {
trace!(target: "miner", "Price info arrived: {:?}", price);
let usd_per_vap = price.vapusd;
let wei_per_usd: f32 = 1.0e18 / usd_per_vap;
let gas_per_tx: f32 = 21000.0;
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${:.2}", usd_per_vap)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
set_price(U256::from(wei_per_gas as u64));
});
self.next_calibration = Instant::now() + self.options.recalibration_period;
}
}
}