fix: backwards compatibility for eth_feeHistory (#395)

* fix: backwards compatibility for eth_feeHistor

* fix: convenience for calling the fee_history method
This commit is contained in:
Rohit Narurkar 2021-08-19 18:44:15 +02:00 committed by GitHub
parent f6412f87d7
commit ab0e3ca0d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 10 deletions

View File

@ -84,8 +84,8 @@ pub use pubsub::{PubsubClient, SubscriptionStream};
use async_trait::async_trait;
use auto_impl::auto_impl;
use ethers_core::types::transaction::{eip2718::TypedTransaction, eip2930::AccessListWithGasUsed};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{error::Error, fmt::Debug, future::Future, pin::Pin};
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
use std::{error::Error, fmt::Debug, future::Future, pin::Pin, str::FromStr};
pub use provider::{FilterKind, Provider, ProviderError};
@ -704,9 +704,9 @@ pub trait Middleware: Sync + Send + Debug {
.map_err(FromErr::from)
}
async fn fee_history(
async fn fee_history<T: Into<U256> + serde::Serialize + Send + Sync>(
&self,
block_count: u64,
block_count: T,
last_block: BlockNumber,
reward_percentiles: &[f64],
) -> Result<FeeHistory, Self::Error> {
@ -733,10 +733,31 @@ pub trait Middleware: Sync + Send + Debug {
pub struct FeeHistory {
pub base_fee_per_gas: Vec<U256>,
pub gas_used_ratio: Vec<f64>,
pub oldest_block: u64,
#[serde(deserialize_with = "from_int_or_hex")]
/// oldestBlock is returned as an unsigned integer up to geth v1.10.6. From
/// geth v1.10.7, this has been updated to return in the hex encoded form.
/// The custom deserializer allows backward compatibility for those clients
/// not running v1.10.7 yet.
pub oldest_block: U256,
pub reward: Vec<Vec<U256>>,
}
fn from_int_or_hex<'de, D>(deserializer: D) -> Result<U256, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum IntOrHex {
Int(u64),
Hex(String),
}
match IntOrHex::deserialize(deserializer)? {
IntOrHex::Int(n) => Ok(U256::from(n)),
IntOrHex::Hex(s) => U256::from_str(s.as_str()).map_err(serde::de::Error::custom),
}
}
#[cfg(feature = "celo")]
#[async_trait]
pub trait CeloMiddleware: Middleware {

View File

@ -769,20 +769,37 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
self.subscribe([logs, filter]).await
}
async fn fee_history(
async fn fee_history<T: Into<U256> + serde::Serialize + Send + Sync>(
&self,
block_count: u64,
block_count: T,
last_block: BlockNumber,
reward_percentiles: &[f64],
) -> Result<FeeHistory, Self::Error> {
let block_count = utils::serialize(&block_count);
let last_block = utils::serialize(&last_block);
let reward_percentiles = utils::serialize(&reward_percentiles);
// The blockCount param is expected to be an unsigned integer up to geth v1.10.6.
// Geth v1.10.7 onwards, this has been updated to a hex encoded form. Failure to
// decode the param from client side would fallback to the old API spec.
self.request(
"eth_feeHistory",
[block_count, last_block, reward_percentiles],
[
utils::serialize(&block_count),
last_block.clone(),
reward_percentiles.clone(),
],
)
.await
.or(self
.request(
"eth_feeHistory",
[
utils::serialize(&block_count.into().as_u64()),
last_block,
reward_percentiles,
],
)
.await)
}
}
@ -1123,7 +1140,7 @@ mod tests {
.unwrap();
let history = provider
.fee_history(10, BlockNumber::Latest, &[10.0, 40.0])
.fee_history(10u64, BlockNumber::Latest, &[10.0, 40.0])
.await
.unwrap();
dbg!(&history);