mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 20:27:58 +00:00
Add an system_syncState RPC method (#7315)
* Add system_syncState RPC method * Update client/rpc-api/src/system/helpers.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
@@ -86,6 +86,18 @@ pub enum NodeRole {
|
||||
Sentry,
|
||||
}
|
||||
|
||||
/// The state of the syncing of the node.
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SyncState<Number> {
|
||||
/// Height of the block at which syncing started.
|
||||
pub starting_block: Number,
|
||||
/// Height of the current best block of the node.
|
||||
pub current_block: Number,
|
||||
/// Height of the highest block learned from the network. Missing if no block is known yet.
|
||||
#[serde(default = "Default::default", skip_serializing_if = "Option::is_none")]
|
||||
pub highest_block: Option<Number>,
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -114,4 +126,25 @@ mod tests {
|
||||
r#"{"peerId":"2","roles":"a","bestHash":5,"bestNumber":6}"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_serialize_sync_state() {
|
||||
assert_eq!(
|
||||
::serde_json::to_string(&SyncState {
|
||||
starting_block: 12u32,
|
||||
current_block: 50u32,
|
||||
highest_block: Some(128u32),
|
||||
}).unwrap(),
|
||||
r#"{"startingBlock":12,"currentBlock":50,"highestBlock":128}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
::serde_json::to_string(&SyncState {
|
||||
starting_block: 12u32,
|
||||
current_block: 50u32,
|
||||
highest_block: None,
|
||||
}).unwrap(),
|
||||
r#"{"startingBlock":12,"currentBlock":50}"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ use futures::{future::BoxFuture, compat::Compat};
|
||||
|
||||
use self::error::Result as SystemResult;
|
||||
|
||||
pub use self::helpers::{SystemInfo, Health, PeerInfo, NodeRole};
|
||||
pub use self::helpers::{SystemInfo, Health, PeerInfo, NodeRole, SyncState};
|
||||
pub use self::gen_client::Client as SystemClient;
|
||||
|
||||
/// Substrate system RPC API
|
||||
@@ -103,4 +103,9 @@ pub trait SystemApi<Hash, Number> {
|
||||
/// Returns the roles the node is running as.
|
||||
#[rpc(name = "system_nodeRoles", returns = "Vec<NodeRole>")]
|
||||
fn system_node_roles(&self) -> Receiver<Vec<NodeRole>>;
|
||||
|
||||
/// Returns the state of the syncing of the node: starting block, current best block, highest
|
||||
/// known block.
|
||||
#[rpc(name = "system_syncState", returns = "SyncState<Number>")]
|
||||
fn system_sync_state(&self) -> Receiver<SyncState<Number>>;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ lazy_static = { version = "1.4.0", optional = true }
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
futures01 = { package = "futures", version = "0.1.29" }
|
||||
lazy_static = "1.4.0"
|
||||
sc-network = { version = "0.8.0", path = "../network" }
|
||||
sp-io = { version = "2.0.0", path = "../../primitives/io" }
|
||||
substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" }
|
||||
|
||||
@@ -30,7 +30,7 @@ use sp_runtime::traits::{self, Header as HeaderT};
|
||||
use self::error::Result;
|
||||
|
||||
pub use sc_rpc_api::system::*;
|
||||
pub use self::helpers::{SystemInfo, Health, PeerInfo, NodeRole};
|
||||
pub use self::helpers::{SystemInfo, Health, PeerInfo, NodeRole, SyncState};
|
||||
pub use self::gen_client::Client as SystemClient;
|
||||
|
||||
macro_rules! bail_if_unsafe {
|
||||
@@ -66,7 +66,9 @@ pub enum Request<B: traits::Block> {
|
||||
/// Must return any potential parse error.
|
||||
NetworkRemoveReservedPeer(String, oneshot::Sender<Result<()>>),
|
||||
/// Must return the node role.
|
||||
NodeRoles(oneshot::Sender<Vec<NodeRole>>)
|
||||
NodeRoles(oneshot::Sender<Vec<NodeRole>>),
|
||||
/// Must return the state of the node syncing.
|
||||
SyncState(oneshot::Sender<SyncState<<B::Header as HeaderT>::Number>>),
|
||||
}
|
||||
|
||||
impl<B: traits::Block> System<B> {
|
||||
@@ -189,4 +191,10 @@ impl<B: traits::Block> SystemApi<B::Hash, <B::Header as HeaderT>::Number> for Sy
|
||||
let _ = self.send_back.unbounded_send(Request::NodeRoles(tx));
|
||||
Receiver(Compat::new(rx))
|
||||
}
|
||||
|
||||
fn system_sync_state(&self) -> Receiver<SyncState<<B::Header as HeaderT>::Number>> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let _ = self.send_back.unbounded_send(Request::SyncState(tx));
|
||||
Receiver(Compat::new(rx))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,13 @@ fn api<T: Into<Option<Status>>>(sync: T) -> System<Block> {
|
||||
Request::NodeRoles(sender) => {
|
||||
let _ = sender.send(vec![NodeRole::Authority]);
|
||||
}
|
||||
Request::SyncState(sender) => {
|
||||
let _ = sender.send(SyncState {
|
||||
starting_block: 1,
|
||||
current_block: 2,
|
||||
highest_block: Some(3),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
future::ready(())
|
||||
@@ -291,6 +298,18 @@ fn system_node_roles() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn system_sync_state() {
|
||||
assert_eq!(
|
||||
wait_receiver(api(None).system_sync_state()),
|
||||
SyncState {
|
||||
starting_block: 1,
|
||||
current_block: 2,
|
||||
highest_block: Some(3),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn system_network_add_reserved() {
|
||||
let good_peer_id = "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV";
|
||||
|
||||
@@ -80,7 +80,7 @@ pub use sc_tracing::TracingReceiver;
|
||||
pub use task_manager::SpawnTaskHandle;
|
||||
pub use task_manager::TaskManager;
|
||||
pub use sp_consensus::import_queue::ImportQueue;
|
||||
use sc_client_api::BlockchainEvents;
|
||||
use sc_client_api::{blockchain::HeaderBackend, BlockchainEvents};
|
||||
|
||||
const DEFAULT_PROTOCOL_ID: &str = "sup";
|
||||
|
||||
@@ -199,7 +199,7 @@ pub struct PartialComponents<Client, Backend, SelectChain, ImportQueue, Transact
|
||||
/// The `status_sink` contain a list of senders to send a periodic network status to.
|
||||
async fn build_network_future<
|
||||
B: BlockT,
|
||||
C: BlockchainEvents<B>,
|
||||
C: BlockchainEvents<B> + HeaderBackend<B>,
|
||||
H: sc_network::ExHashT
|
||||
> (
|
||||
role: Role,
|
||||
@@ -212,6 +212,9 @@ async fn build_network_future<
|
||||
) {
|
||||
let mut imported_blocks_stream = client.import_notification_stream().fuse();
|
||||
|
||||
// Current best block at initialization, to report to the RPC layer.
|
||||
let starting_block = client.info().best_number;
|
||||
|
||||
// Stream of finalized blocks reported by the client.
|
||||
let mut finality_notification_stream = {
|
||||
let mut finality_notification_stream = client.finality_notification_stream().fuse();
|
||||
@@ -323,6 +326,15 @@ async fn build_network_future<
|
||||
|
||||
let _ = sender.send(vec![node_role]);
|
||||
}
|
||||
sc_rpc::system::Request::SyncState(sender) => {
|
||||
use sc_rpc::system::SyncState;
|
||||
|
||||
let _ = sender.send(SyncState {
|
||||
starting_block: starting_block,
|
||||
current_block: client.info().best_number,
|
||||
highest_block: network.best_seen_block(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user