From 2147407f5a129a69461319395da41d16ff6206ea Mon Sep 17 00:00:00 2001
From: tgmichel <telmo@purestake.com>
Date: Fri, 16 Oct 2020 12:41:02 +0200
Subject: [PATCH] Return correct response in `eth_syncing` (#164)

---
 rpc/src/eth.rs           | 39 +++++++++++++++++++++++++--------------
 template/node/src/rpc.rs |  1 +
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/rpc/src/eth.rs b/rpc/src/eth.rs
index a7ab4c314..a4d4da157 100644
--- a/rpc/src/eth.rs
+++ b/rpc/src/eth.rs
@@ -28,6 +28,7 @@ use sc_client_api::backend::{StorageProvider, Backend, StateBackend, AuxStore};
 use sha3::{Keccak256, Digest};
 use sp_runtime::traits::BlakeTwo256;
 use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend};
+use sc_network::{NetworkService, ExHashT};
 use frontier_rpc_core::{EthApi as EthApiT, NetApi as NetApiT};
 use frontier_rpc_core::types::{
 	BlockNumber, Bytes, CallRequest, Filter, Index, Log, Receipt, RichBlock,
@@ -38,22 +39,24 @@ use crate::internal_err;
 
 pub use frontier_rpc_core::{EthApiServer, NetApiServer};
 
-pub struct EthApi<B: BlockT, C, P, CT, BE> {
+pub struct EthApi<B: BlockT, C, P, CT, BE, H: ExHashT> {
 	pool: Arc<P>,
 	client: Arc<C>,
 	convert_transaction: CT,
+	network: Arc<NetworkService<B, H>>,
 	is_authority: bool,
 	_marker: PhantomData<(B, BE)>,
 }
 
-impl<B: BlockT, C, P, CT, BE> EthApi<B, C, P, CT, BE> {
+impl<B: BlockT, C, P, CT, BE, H: ExHashT> EthApi<B, C, P, CT, BE, H> {
 	pub fn new(
 		client: Arc<C>,
 		pool: Arc<P>,
 		convert_transaction: CT,
+		network: Arc<NetworkService<B, H>>,
 		is_authority: bool
 	) -> Self {
-		Self { client, pool, convert_transaction, is_authority, _marker: PhantomData }
+		Self { client, pool, convert_transaction, network, is_authority, _marker: PhantomData }
 	}
 }
 
@@ -168,7 +171,7 @@ fn transaction_build(
 	}
 }
 
-impl<B, C, P, CT, BE> EthApi<B, C, P, CT, BE> where
+impl<B, C, P, CT, BE, H: ExHashT> EthApi<B, C, P, CT, BE, H> where
 	C: ProvideRuntimeApi<B> + StorageProvider<B, BE> + AuxStore,
 	C: HeaderBackend<B> + HeaderMetadata<B, Error=BlockChainError> + 'static,
 	C::Api: EthereumRuntimeRPCApi<B>,
@@ -227,7 +230,7 @@ impl<B, C, P, CT, BE> EthApi<B, C, P, CT, BE> where
 	}
 }
 
-impl<B, C, P, CT, BE> EthApiT for EthApi<B, C, P, CT, BE> where
+impl<B, C, P, CT, BE, H: ExHashT> EthApiT for EthApi<B, C, P, CT, BE, H> where
 	C: ProvideRuntimeApi<B> + StorageProvider<B, BE> + AuxStore,
 	C: HeaderBackend<B> + HeaderMetadata<B, Error=BlockChainError> + 'static,
 	C::Api: EthereumRuntimeRPCApi<B>,
@@ -243,15 +246,23 @@ impl<B, C, P, CT, BE> EthApiT for EthApi<B, C, P, CT, BE> where
 	}
 
 	fn syncing(&self) -> Result<SyncStatus> {
-		let block_number = U256::from(self.client.info().best_number.clone().unique_saturated_into());
-
-		Ok(SyncStatus::Info(SyncInfo {
-			starting_block: U256::zero(),
-			current_block: block_number,
-			highest_block: block_number,
-			warp_chunks_amount: None,
-			warp_chunks_processed: None,
-		}))
+		if self.network.is_major_syncing() {
+			let block_number = U256::from(
+				self.client.info().best_number.clone().unique_saturated_into()
+			);
+			Ok(SyncStatus::Info(SyncInfo {
+				starting_block: U256::zero(),
+				current_block: block_number,
+				// TODO `highest_block` is not correct, should load `best_seen_block` from NetworkWorker,
+				// but afaik that is not currently possible in Substrate:
+				// https://github.com/paritytech/substrate/issues/7311
+				highest_block: block_number,
+				warp_chunks_amount: None,
+				warp_chunks_processed: None,
+			}))
+		} else {
+			Ok(SyncStatus::None)
+		}
 	}
 
 	fn hashrate(&self) -> Result<U256> {
diff --git a/template/node/src/rpc.rs b/template/node/src/rpc.rs
index 74ce5b593..828163b7d 100644
--- a/template/node/src/rpc.rs
+++ b/template/node/src/rpc.rs
@@ -106,6 +106,7 @@ pub fn create_full<C, P, BE>(
 			client.clone(),
 			pool.clone(),
 			frontier_template_runtime::TransactionConverter,
+			network.clone(),
 			is_authority,
 		))
 	);