add eth_syncing RPC (#848)

* add eth_syncing RPC

* Changelo updated

* small comments

* Intermediate SyncingStatus
This commit is contained in:
rakita 2022-02-01 11:58:45 +01:00 committed by GitHub
parent 5fefb2b721
commit 24e7c471e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 2 deletions

View File

@ -4,6 +4,7 @@
### Unreleased ### Unreleased
- Add `eth_syncing` [848](https://github.com/gakonst/ethers-rs/pull/848)
- Fix overflow and possible divide-by-zero in `estimate_priority_fee` - Fix overflow and possible divide-by-zero in `estimate_priority_fee`
- Add BSC mainnet and testnet to the list of known chains - Add BSC mainnet and testnet to the list of known chains
[831](https://github.com/gakonst/ethers-rs/pull/831) [831](https://github.com/gakonst/ethers-rs/pull/831)

View File

@ -79,6 +79,15 @@ where
} }
} }
/// Structure used in eth_syncing RPC
#[derive(Clone, Debug)]
pub enum SyncingStatus {
/// When client is synced to highest block, eth_syncing with return string "false"
IsFalse,
/// When client is still syncing past blocks we get IsSyncing information.
IsSyncing { starting_block: U256, current_block: U256, highest_block: U256 },
}
/// A middleware allows customizing requests send and received from an ethereum node. /// A middleware allows customizing requests send and received from an ethereum node.
/// ///
/// Writing a middleware is as simple as: /// Writing a middleware is as simple as:
@ -303,6 +312,10 @@ pub trait Middleware: Sync + Send + Debug {
self.inner().call(tx, block).await.map_err(FromErr::from) self.inner().call(tx, block).await.map_err(FromErr::from)
} }
async fn syncing(&self) -> Result<SyncingStatus, Self::Error> {
self.inner().syncing().await.map_err(FromErr::from)
}
async fn get_chainid(&self) -> Result<U256, Self::Error> { async fn get_chainid(&self) -> Result<U256, Self::Error> {
self.inner().get_chainid().await.map_err(FromErr::from) self.inner().get_chainid().await.map_err(FromErr::from)
} }

View File

@ -3,7 +3,7 @@ use crate::{
pubsub::{PubsubClient, SubscriptionStream}, pubsub::{PubsubClient, SubscriptionStream},
stream::{FilterWatcher, DEFAULT_POLL_INTERVAL}, stream::{FilterWatcher, DEFAULT_POLL_INTERVAL},
FromErr, Http as HttpProvider, JsonRpcClient, JsonRpcClientWrapper, MockProvider, FromErr, Http as HttpProvider, JsonRpcClient, JsonRpcClientWrapper, MockProvider,
PendingTransaction, QuorumProvider, PendingTransaction, QuorumProvider, SyncingStatus,
}; };
#[cfg(feature = "celo")] #[cfg(feature = "celo")]
@ -23,7 +23,7 @@ use ethers_core::{
utils, utils,
}; };
use hex::FromHex; use hex::FromHex;
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
use url::{ParseError, Url}; use url::{ParseError, Url};
@ -497,6 +497,30 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
self.request("eth_chainId", ()).await self.request("eth_chainId", ()).await
} }
/// Return current client syncing status. If IsFalse sync is over.
async fn syncing(&self) -> Result<SyncingStatus, Self::Error> {
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SyncingStatusIntermediate {
/// When client is synced to highest block, eth_syncing with return string "false"
IsFalse(bool),
/// When client is still syncing past blocks we get IsSyncing information.
IsSyncing { starting_block: U256, current_block: U256, highest_block: U256 },
}
let intermediate: SyncingStatusIntermediate = self.request("eth_syncing", ()).await?;
match intermediate {
SyncingStatusIntermediate::IsFalse(false) => Ok(SyncingStatus::IsFalse),
SyncingStatusIntermediate::IsFalse(true) => Err(ProviderError::CustomError(
"eth_syncing returned `true` that is undefined value.".to_owned(),
)),
SyncingStatusIntermediate::IsSyncing {
starting_block,
current_block,
highest_block,
} => Ok(SyncingStatus::IsSyncing { starting_block, current_block, highest_block }),
}
}
/// Returns the network version. /// Returns the network version.
async fn get_net_version(&self) -> Result<U64, ProviderError> { async fn get_net_version(&self) -> Result<U64, ProviderError> {
self.request("net_version", ()).await self.request("net_version", ()).await