Use provided usd-per-eth value if an endpoint is specified (#11209)

* Fix `invalid transaction price` error message

* Setup Calibrated GasPriceConfig when usd-per-eth is an endpoint

The change will try to check if the specified value is an endpoint.
If the value of `auto` is specified, the default endpoint URL will be used
otherwise, the user-provided value will be taken as-is for an endpoint.

* Use if-let and check for usd-per-eth arg:

1. auto = use etherscan
2. value = use fixed pricer
3. endpoint = use the provided endpoint as-is

* Fix typo in to_pricce error message

* Correct whitespace indentation

* Use arg_usd_per_eth directly
This commit is contained in:
Rakan Alhneiti 2019-10-29 12:18:30 +01:00 committed by Marek Kotewicz
parent 0d3423cbe0
commit 6993ec9531
6 changed files with 35 additions and 22 deletions

View File

@ -1910,6 +1910,7 @@ mod tests {
}, },
fetch, fetch,
p, p,
"fake_endpoint".to_owned()
) )
) )
} }

View File

@ -57,8 +57,7 @@ impl<F> cmp::PartialEq for Client<F> {
impl<F: Fetch> Client<F> { impl<F: Fetch> Client<F> {
/// Creates a new instance of the `Client` given a `fetch::Client`. /// Creates a new instance of the `Client` given a `fetch::Client`.
pub fn new(fetch: F, pool: Executor) -> Client<F> { pub fn new(fetch: F, pool: Executor, api_endpoint: String) -> Client<F> {
let api_endpoint = "https://api.etherscan.io/api?module=stats&action=ethprice".to_owned();
Client { pool, api_endpoint, fetch } Client { pool, api_endpoint, fetch }
} }
@ -105,11 +104,11 @@ mod test {
use super::Client; use super::Client;
fn price_info_ok(response: &str, executor: Executor) -> Client<FakeFetch<String>> { fn price_info_ok(response: &str, executor: Executor) -> Client<FakeFetch<String>> {
Client::new(FakeFetch::new(Some(response.to_owned())), executor) Client::new(FakeFetch::new(Some(response.to_owned())), executor, "fake_endpoint".to_owned())
} }
fn price_info_not_found(executor: Executor) -> Client<FakeFetch<String>> { fn price_info_not_found(executor: Executor) -> Client<FakeFetch<String>> {
Client::new(FakeFetch::new(None::<String>), executor) Client::new(FakeFetch::new(None::<String>), executor, "fake_endpoint".to_owned())
} }
#[test] #[test]

View File

@ -43,11 +43,11 @@ pub struct GasPriceCalibrator {
impl GasPriceCalibrator { impl GasPriceCalibrator {
/// Create a new gas price calibrator. /// Create a new gas price calibrator.
pub fn new(options: GasPriceCalibratorOptions, fetch: FetchClient, p: Executor) -> GasPriceCalibrator { pub fn new(options: GasPriceCalibratorOptions, fetch: FetchClient, p: Executor, api_endpoint: String) -> GasPriceCalibrator {
GasPriceCalibrator { GasPriceCalibrator {
options: options, options: options,
next_calibration: Instant::now(), next_calibration: Instant::now(),
price_info: PriceInfoClient::new(fetch, p), price_info: PriceInfoClient::new(fetch, p, api_endpoint),
} }
} }

View File

@ -58,6 +58,7 @@ use network::{IpFilter};
const DEFAULT_MAX_PEERS: u16 = 50; const DEFAULT_MAX_PEERS: u16 = 50;
const DEFAULT_MIN_PEERS: u16 = 25; const DEFAULT_MIN_PEERS: u16 = 25;
pub const ETHERSCAN_ETH_PRICE_ENDPOINT: &str = "https://api.etherscan.io/api?module=stats&action=ethprice";
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Cmd { pub enum Cmd {
@ -666,23 +667,30 @@ impl Configuration {
} }
let usd_per_tx = to_price(&self.args.arg_usd_per_tx)?; let usd_per_tx = to_price(&self.args.arg_usd_per_tx)?;
if "auto" == self.args.arg_usd_per_eth.as_str() {
return Ok(GasPricerConfig::Calibrated { if "auto" == self.args.arg_usd_per_eth {
Ok(GasPricerConfig::Calibrated {
usd_per_tx: usd_per_tx, usd_per_tx: usd_per_tx,
recalibration_period: to_duration(self.args.arg_price_update_period.as_str())?, recalibration_period: to_duration(self.args.arg_price_update_period.as_str())?,
}); api_endpoint: ETHERSCAN_ETH_PRICE_ENDPOINT.to_string(),
})
} else if let Ok(usd_per_eth_parsed) = to_price(&self.args.arg_usd_per_eth) {
let wei_per_gas = wei_per_gas(usd_per_tx, usd_per_eth_parsed);
info!(
"Using a fixed conversion rate of Ξ1 = {} ({} wei/gas)",
Colour::White.bold().paint(format!("US${:.2}", usd_per_eth_parsed)),
Colour::Yellow.bold().paint(format!("{}", wei_per_gas))
);
Ok(GasPricerConfig::Fixed(wei_per_gas))
} else {
Ok(GasPricerConfig::Calibrated {
usd_per_tx: usd_per_tx,
recalibration_period: to_duration(self.args.arg_price_update_period.as_str())?,
api_endpoint: self.args.arg_usd_per_eth.clone(),
})
} }
let usd_per_eth = to_price(&self.args.arg_usd_per_eth)?;
let wei_per_gas = wei_per_gas(usd_per_tx, usd_per_eth);
info!(
"Using a fixed conversion rate of Ξ1 = {} ({} wei/gas)",
Colour::White.bold().paint(format!("US${:.2}", usd_per_eth)),
Colour::Yellow.bold().paint(format!("{}", wei_per_gas))
);
Ok(GasPricerConfig::Fixed(wei_per_gas))
} }
fn extra_data(&self) -> Result<Bytes, String> { fn extra_data(&self) -> Result<Bytes, String> {

View File

@ -146,7 +146,7 @@ pub fn to_addresses(s: &Option<String>) -> Result<Vec<Address>, String> {
/// Tries to parse string as a price. /// Tries to parse string as a price.
pub fn to_price(s: &str) -> Result<f32, String> { pub fn to_price(s: &str) -> Result<f32, String> {
s.parse::<f32>().map_err(|_| format!("Invalid transaciton price 's' given. Must be a decimal number.")) s.parse::<f32>().map_err(|_| format!("Invalid transaction price {:?} given. Must be a decimal number.", s))
} }
pub fn join_set(set: Option<&HashSet<String>>) -> Option<String> { pub fn join_set(set: Option<&HashSet<String>>) -> Option<String> {

View File

@ -29,6 +29,8 @@ use parity_version::version_data;
use user_defaults::UserDefaults; use user_defaults::UserDefaults;
use types::client_types::Mode; use types::client_types::Mode;
use crate::configuration;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum SpecType { pub enum SpecType {
Foundation, Foundation,
@ -248,6 +250,7 @@ pub enum GasPricerConfig {
Calibrated { Calibrated {
usd_per_tx: f32, usd_per_tx: f32,
recalibration_period: Duration, recalibration_period: Duration,
api_endpoint: String
} }
} }
@ -256,6 +259,7 @@ impl Default for GasPricerConfig {
GasPricerConfig::Calibrated { GasPricerConfig::Calibrated {
usd_per_tx: 0.0001f32, usd_per_tx: 0.0001f32,
recalibration_period: Duration::from_secs(3600), recalibration_period: Duration::from_secs(3600),
api_endpoint: configuration::ETHERSCAN_ETH_PRICE_ENDPOINT.to_string(),
} }
} }
} }
@ -264,7 +268,7 @@ impl GasPricerConfig {
pub fn to_gas_pricer(&self, fetch: FetchClient, p: Executor) -> GasPricer { pub fn to_gas_pricer(&self, fetch: FetchClient, p: Executor) -> GasPricer {
match *self { match *self {
GasPricerConfig::Fixed(u) => GasPricer::Fixed(u), GasPricerConfig::Fixed(u) => GasPricer::Fixed(u),
GasPricerConfig::Calibrated { usd_per_tx, recalibration_period, .. } => { GasPricerConfig::Calibrated { usd_per_tx, recalibration_period, ref api_endpoint } => {
GasPricer::new_calibrated( GasPricer::new_calibrated(
GasPriceCalibrator::new( GasPriceCalibrator::new(
GasPriceCalibratorOptions { GasPriceCalibratorOptions {
@ -273,6 +277,7 @@ impl GasPricerConfig {
}, },
fetch, fetch,
p, p,
api_endpoint.clone(),
) )
) )
} }