Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
fix(middleware): polygon gas stations (#2479)
Browse files Browse the repository at this point in the history
* fix(middleware): polygon gas stations

* fix: wasm
  • Loading branch information
DaniPopes authored Jun 17, 2023
1 parent 624a460 commit b730b74
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
8 changes: 5 additions & 3 deletions ethers-middleware/src/gas_escalator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ pub trait GasEscalator: Send + Sync + std::fmt::Debug {
fn get_gas_price(&self, initial_price: U256, time_elapsed: u64) -> U256;
}

#[derive(Error, Debug)]
/// Error thrown when the GasEscalator interacts with the blockchain
#[derive(Debug, Error)]
pub enum GasEscalatorError<M: Middleware> {
#[error("{0}")]
/// Thrown when an internal middleware errors
Expand All @@ -63,8 +63,8 @@ impl<M: Middleware> MiddlewareError for GasEscalatorError<M> {
}
}

#[derive(Debug, Clone, Copy)]
/// The frequency at which transactions will be bumped
#[derive(Debug, Clone, Copy)]
pub enum Frequency {
/// On a per block basis using the eth_newBlock filter
PerBlock,
Expand All @@ -81,7 +81,6 @@ pub(crate) struct GasEscalatorMiddlewareInternal<M> {
_background: oneshot::Sender<()>,
}

#[derive(Debug, Clone)]
/// A Gas escalator allows bumping transactions' gas price to avoid getting them
/// stuck in the memory pool.
///
Expand Down Expand Up @@ -137,6 +136,7 @@ pub(crate) struct GasEscalatorMiddlewareInternal<M> {
/// let gas_oracle = GasNow::new().category(GasCategory::SafeLow);
/// let provider = GasOracleMiddleware::new(provider, gas_oracle);
/// ```
#[derive(Debug, Clone)]
pub struct GasEscalatorMiddleware<M> {
pub(crate) inner: Arc<GasEscalatorMiddlewareInternal<M>>,
}
Expand Down Expand Up @@ -229,6 +229,7 @@ where
}
}

#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug)]
pub struct EscalationTask<M, E> {
inner: M,
Expand All @@ -238,6 +239,7 @@ pub struct EscalationTask<M, E> {
shutdown: oneshot::Receiver<()>,
}

#[cfg(not(target_arch = "wasm32"))]
impl<M, E> EscalationTask<M, E> {
pub fn new(
inner: M,
Expand Down
41 changes: 37 additions & 4 deletions ethers-middleware/src/gas_oracle/polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use reqwest::Client;
use serde::Deserialize;
use url::Url;

const MAINNET_URL: &str = "https://gasstation-mainnet.matic.network/v2";
const MUMBAI_URL: &str = "https://gasstation-mumbai.matic.today/v2";
const MAINNET_URL: &str = "https://gasstation.polygon.technology/v2";
const MUMBAI_URL: &str = "https://gasstation-testnet.polygon.technology/v2";

/// The [Polygon](https://docs.polygon.technology/docs/develop/tools/polygon-gas-station/) gas station API
/// Queries over HTTP and implements the `GasOracle` trait.
Expand All @@ -24,6 +24,7 @@ pub struct Polygon {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Response {
#[serde(deserialize_with = "deserialize_stringified_f64")]
pub estimated_base_fee: f64,
pub safe_low: GasEstimate,
pub standard: GasEstimate,
Expand All @@ -33,10 +34,28 @@ pub struct Response {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct GasEstimate {
#[serde(deserialize_with = "deserialize_stringified_f64")]
pub max_priority_fee: f64,
#[serde(deserialize_with = "deserialize_stringified_f64")]
pub max_fee: f64,
}

fn deserialize_stringified_f64<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum F64OrString {
F64(serde_json::Number),
String(String),
}
match Deserialize::deserialize(deserializer)? {
F64OrString::F64(f) => f.as_f64().ok_or_else(|| serde::de::Error::custom("invalid f64")),
F64OrString::String(s) => s.parse().map_err(serde::de::Error::custom),
}
}

impl Response {
#[inline]
pub fn estimate_from_category(&self, gas_category: GasCategory) -> GasEstimate {
Expand Down Expand Up @@ -77,7 +96,15 @@ impl GasOracle for Polygon {

impl Polygon {
pub fn new(chain: Chain) -> Result<Self> {
Self::with_client(Client::new(), chain)
#[cfg(not(target_arch = "wasm32"))]
static APP_USER_AGENT: &str =
concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);

let builder = Client::builder();
#[cfg(not(target_arch = "wasm32"))]
let builder = builder.user_agent(APP_USER_AGENT);

Self::with_client(builder.build()?, chain)
}

pub fn with_client(client: Client, chain: Chain) -> Result<Self> {
Expand Down Expand Up @@ -110,7 +137,13 @@ mod tests {

#[test]
fn parse_polygon_gas_station_response() {
let s = r#"{"safeLow":{"maxPriorityFee":2.1267086610666666,"maxFee":2.1267086760666665},"standard":{"maxPriorityFee":2.3482958369333335,"maxFee":2.3482958519333335},"fast":{"maxPriorityFee":2.793454819,"maxFee":2.793454834},"estimatedBaseFee":1.5e-8,"blockTime":2,"blockNumber":30328888}"#;
let s = r#"{"safeLow":{"maxPriorityFee":"30.739827732","maxFee":"335.336914674"},"standard":{"maxPriorityFee":"57.257993430","maxFee":"361.855080372"},"fast":{"maxPriorityFee":"103.414268558","maxFee":"408.011355500"},"estimatedBaseFee":"304.597086942","blockTime":2,"blockNumber":43975155}"#;
let _resp: Response = serde_json::from_str(s).unwrap();
}

#[test]
fn parse_polygon_testnet_gas_station_response() {
let s = r#"{"safeLow":{"maxPriorityFee":1.3999999978,"maxFee":1.4000000157999999},"standard":{"maxPriorityFee":1.5199999980666665,"maxFee":1.5200000160666665},"fast":{"maxPriorityFee":2.0233333273333334,"maxFee":2.0233333453333335},"estimatedBaseFee":1.8e-8,"blockTime":2,"blockNumber":36917340}"#;
let _resp: Response = serde_json::from_str(s).unwrap();
}
}

0 comments on commit b730b74

Please sign in to comment.