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

add eth_syncing RPC #848

Merged
merged 4 commits into from
Feb 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Unreleased

- Add `eth_syncing` [848](https://github.com/gakonst/ethers-rs/pull/848)
- Fix overflow and possible divide-by-zero in `estimate_priority_fee`
- Add BSC mainnet and testnet to the list of known chains
[831](https://github.com/gakonst/ethers-rs/pull/831)
Expand Down
13 changes: 13 additions & 0 deletions ethers-providers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
/// Writing a middleware is as simple as:
Expand Down Expand Up @@ -303,6 +312,10 @@ pub trait Middleware: Sync + Send + Debug {
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> {
self.inner().get_chainid().await.map_err(FromErr::from)
}
Expand Down
28 changes: 26 additions & 2 deletions ethers-providers/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
pubsub::{PubsubClient, SubscriptionStream},
stream::{FilterWatcher, DEFAULT_POLL_INTERVAL},
FromErr, Http as HttpProvider, JsonRpcClient, JsonRpcClientWrapper, MockProvider,
PendingTransaction, QuorumProvider,
PendingTransaction, QuorumProvider, SyncingStatus,
};

#[cfg(feature = "celo")]
Expand All @@ -23,7 +23,7 @@ use ethers_core::{
utils,
};
use hex::FromHex;
use serde::{de::DeserializeOwned, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use thiserror::Error;
use url::{ParseError, Url};

Expand Down Expand Up @@ -497,6 +497,30 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
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.
async fn get_net_version(&self) -> Result<U64, ProviderError> {
self.request("net_version", ()).await
Expand Down