diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index fbd4fe8ed..491bdde10 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -293,15 +293,13 @@ impl Eth for EthClient where let chain_info = client.chain_info(); let current_block = U256::from(chain_info.best_block_number); let highest_block = U256::from(status.highest_block_number.unwrap_or(status.start_block_number)); - let gap = chain_info.ancient_block_number.map(|x| U256::from(x + 1)) - .and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last)))); + let info = SyncInfo { starting_block: status.start_block_number.into(), current_block: current_block.into(), highest_block: highest_block.into(), warp_chunks_amount: warp_chunks_amount.map(|x| U256::from(x as u64)).map(Into::into), warp_chunks_processed: warp_chunks_processed.map(|x| U256::from(x as u64)).map(Into::into), - block_gap: gap.map(|(x, y)| (x.into(), y.into())), }; Ok(SyncStatus::Info(info)) } else { diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index 326dc9c2b..3c14ea39e 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -40,7 +40,7 @@ use v1::types::{ Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, - OperationsInfo + OperationsInfo, ChainStatus, }; use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings}; use v1::helpers::dispatch::DEFAULT_MAC; @@ -385,4 +385,17 @@ impl Parity for ParityClient where let updater = take_weak!(self.updater); Ok(updater.info().map(Into::into)) } + + fn chain_status(&self) -> Result { + try!(self.active()); + + let chain_info = take_weak!(self.client).chain_info(); + + let gap = chain_info.ancient_block_number.map(|x| U256::from(x + 1)) + .and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last)))); + + Ok(ChainStatus { + block_gap: gap.map(|(x, y)| (x.into(), y.into())), + }) + } } diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 35790a29f..c0566589e 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -137,16 +137,15 @@ fn rpc_eth_syncing() { // "sync" to 1000 blocks. // causes TestBlockChainClient to return 1000 for its best block number. tester.add_blocks(1000, EachBlockWith::Nothing); - *tester.client.ancient_block.write() = Some((H256::new(), 5)); - *tester.client.first_block.write() = Some((H256::from(U256::from(1234)), 3333)); - let true_res = r#"{"jsonrpc":"2.0","result":{"blockGap":["0x6","0xd05"],"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}"#; + + let true_res = r#"{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}"#; assert_eq!(tester.io.handle_request_sync(request), Some(true_res.to_owned())); *tester.client.ancient_block.write() = None; *tester.client.first_block.write() = None; - let snap_res = r#"{"jsonrpc":"2.0","result":{"blockGap":null,"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":"0x32","warpChunksProcessed":"0x18"},"id":1}"#; + let snap_res = r#"{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":"0x32","warpChunksProcessed":"0x18"},"id":1}"#; tester.snapshot.set_status(RestorationStatus::Ongoing { state_chunks: 40, block_chunks: 10, diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index ca5c9b8db..2ab5ba2ce 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -421,3 +421,18 @@ fn rpc_parity_local_transactions() { assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } +#[test] +fn rpc_parity_chain_status() { + use util::{H256, U256}; + + let deps = Dependencies::new(); + let io = deps.default_client(); + + *deps.client.ancient_block.write() = Some((H256::default(), 5)); + *deps.client.first_block.write() = Some((H256::from(U256::from(1234)), 3333)); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_chainStatus", "params":[], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"blockGap":["0x6","0xd05"]},"id":1}"#; + + assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); +} diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index d0e3b16ee..9c8d61bf4 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -26,7 +26,7 @@ use v1::types::{ Peers, Transaction, RpcSettings, Histogram, TransactionStats, LocalTransactionStatus, BlockNumber, ConsensusCapability, VersionInfo, - OperationsInfo + OperationsInfo, ChainStatus, }; build_rpc_trait! { @@ -174,5 +174,9 @@ build_rpc_trait! { /// Get information concerning the latest releases if available. #[rpc(name = "parity_releasesInfo")] fn releases_info(&self) -> Result, Error>; + + /// Get the current chain status. + #[rpc(name = "parity_chainStatus")] + fn chain_status(&self) -> Result; } } diff --git a/rpc/src/v1/types/mod.rs.in b/rpc/src/v1/types/mod.rs.in index 7c7c56c9a..954622a74 100644 --- a/rpc/src/v1/types/mod.rs.in +++ b/rpc/src/v1/types/mod.rs.in @@ -49,7 +49,10 @@ pub use self::filter::{Filter, FilterChanges}; pub use self::hash::{H64, H160, H256, H512, H520, H2048}; pub use self::index::Index; pub use self::log::Log; -pub use self::sync::{SyncStatus, SyncInfo, Peers, PeerInfo, PeerNetworkInfo, PeerProtocolsInfo, PeerEthereumProtocolInfo, TransactionStats}; +pub use self::sync::{ + SyncStatus, SyncInfo, Peers, PeerInfo, PeerNetworkInfo, PeerProtocolsInfo, PeerEthereumProtocolInfo, + TransactionStats, ChainStatus +}; pub use self::transaction::{Transaction, RichRawTransaction, LocalTransactionStatus}; pub use self::transaction_request::TransactionRequest; pub use self::receipt::Receipt; @@ -59,4 +62,4 @@ pub use self::trace_filter::TraceFilter; pub use self::uint::{U128, U256}; pub use self::work::Work; pub use self::histogram::Histogram; -pub use self::consensus_status::*; \ No newline at end of file +pub use self::consensus_status::*; diff --git a/rpc/src/v1/types/sync.rs b/rpc/src/v1/types/sync.rs index 837b425d7..d0e3c7c99 100644 --- a/rpc/src/v1/types/sync.rs +++ b/rpc/src/v1/types/sync.rs @@ -37,9 +37,6 @@ pub struct SyncInfo { /// Warp sync snpashot chunks processed. #[serde(rename="warpChunksProcessed")] pub warp_chunks_processed: Option, - /// Describes the gap in the blockchain, if there is one: (first, last) - #[serde(rename="blockGap")] - pub block_gap: Option<(U256, U256)>, } /// Peers info @@ -162,17 +159,25 @@ impl From for TransactionStats { } } +/// Chain status. +#[derive(Default, Debug, Serialize)] +pub struct ChainStatus { + /// Describes the gap in the blockchain, if there is one: (first, last) + #[serde(rename="blockGap")] + pub block_gap: Option<(U256, U256)>, +} + #[cfg(test)] mod tests { use serde_json; use std::collections::BTreeMap; - use super::{SyncInfo, SyncStatus, Peers, TransactionStats}; + use super::{SyncInfo, SyncStatus, Peers, TransactionStats, ChainStatus}; #[test] fn test_serialize_sync_info() { let t = SyncInfo::default(); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null,"blockGap":null}"#); + assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null}"#); } #[test] @@ -190,16 +195,19 @@ mod tests { let t = SyncStatus::Info(SyncInfo::default()); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null,"blockGap":null}"#); + assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null}"#); } #[test] fn test_serialize_block_gap() { - let mut t = SyncInfo::default(); + let mut t = ChainStatus::default(); + let serialized = serde_json::to_string(&t).unwrap(); + assert_eq!(serialized, r#"{"blockGap":null}"#); + t.block_gap = Some((1.into(), 5.into())); let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null,"blockGap":["0x1","0x5"]}"#) + assert_eq!(serialized, r#"{"blockGap":["0x1","0x5"]}"#); } #[test]