fix(providers): handle zst params in retry provider correctly (#1481)

This commit is contained in:
Matthias Seitz 2022-07-14 19:56:35 +02:00 committed by GitHub
parent 5b981d84c7
commit d509f7a7c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 5 deletions

View File

@ -5,7 +5,6 @@ use super::{common::JsonRpcError, http::ClientError};
use crate::{provider::ProviderError, JsonRpcClient}; use crate::{provider::ProviderError, JsonRpcClient};
use std::{ use std::{
clone::Clone,
fmt::Debug, fmt::Debug,
sync::atomic::{AtomicU32, Ordering}, sync::atomic::{AtomicU32, Ordering},
time::Duration, time::Duration,
@ -135,10 +134,23 @@ where
A: std::fmt::Debug + Serialize + Send + Sync, A: std::fmt::Debug + Serialize + Send + Sync,
R: DeserializeOwned, R: DeserializeOwned,
{ {
let ahead_in_queue = self.requests_enqueued.fetch_add(1, Ordering::SeqCst) as u64; // Helper type that caches the `params` value across several retries
// This is necessary because the wrapper provider is supposed to skip he `params` if it's of
// size 0, see `crate::transports::common::Request`
enum RetryParams<Params> {
Value(Params),
Zst(()),
}
let params = if std::mem::size_of::<A>() == 0 {
RetryParams::Zst(())
} else {
let params = let params =
serde_json::to_value(params).map_err(|err| RetryClientError::SerdeJson(err))?; serde_json::to_value(params).map_err(|err| RetryClientError::SerdeJson(err))?;
RetryParams::Value(params)
};
let ahead_in_queue = self.requests_enqueued.fetch_add(1, Ordering::SeqCst) as u64;
let mut retry_number: u32 = 0; let mut retry_number: u32 = 0;
@ -148,7 +160,11 @@ where
// hack to not hold `R` across an await in the sleep future and prevent requiring // hack to not hold `R` across an await in the sleep future and prevent requiring
// R: Send + Sync // R: Send + Sync
{ {
match self.inner.request(method, params.clone()).await { let resp = match params {
RetryParams::Value(ref params) => self.inner.request(method, params).await,
RetryParams::Zst(unit) => self.inner.request(method, unit).await,
};
match resp {
Ok(ret) => { Ok(ret) => {
self.requests_enqueued.fetch_sub(1, Ordering::SeqCst); self.requests_enqueued.fetch_sub(1, Ordering::SeqCst);
return Ok(ret) return Ok(ret)

View File

@ -91,6 +91,28 @@ mod eth_tests {
let (_max_fee_per_gas, _max_priority_fee_per_gas) = let (_max_fee_per_gas, _max_priority_fee_per_gas) =
provider.estimate_eip1559_fees(None).await.unwrap(); provider.estimate_eip1559_fees(None).await.unwrap();
} }
#[tokio::test]
#[ignore]
async fn test_hardhat_compatibility() {
use ethers_providers::RetryClient;
async fn send_zst_requests<M: Middleware>(provider: M) {
let _ = provider.get_chainid().await.unwrap();
let _ = provider.get_block_number().await.unwrap();
let _ = provider.get_gas_price().await.unwrap();
let _ = provider.get_accounts().await.unwrap();
let _ = provider.get_net_version().await.unwrap();
}
let provider = Provider::<Http>::try_from("http://localhost:8545").unwrap();
send_zst_requests(provider).await;
let provider =
Provider::<RetryClient<Http>>::new_client("http://localhost:8545", 10, 200).unwrap();
send_zst_requests(provider).await;
}
} }
#[cfg(feature = "celo")] #[cfg(feature = "celo")]