1// This file is part of Substrate.
23// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
56// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
1011// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
1516// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
1819//! Substrate system API helpers.
2021use sc_chain_spec::{ChainType, Properties};
22use serde::{Deserialize, Serialize};
23use std::fmt;
2425/// Running node's static details.
26#[derive(Clone, Debug)]
27pub struct SystemInfo {
28/// Implementation name.
29pub impl_name: String,
30/// Implementation version.
31pub impl_version: String,
32/// Chain name.
33pub chain_name: String,
34/// A custom set of properties defined in the chain spec.
35pub properties: Properties,
36/// The type of this chain.
37pub chain_type: ChainType,
38}
3940/// Health struct returned by the RPC
41#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43pub struct Health {
44/// Number of connected peers
45pub peers: usize,
46/// Is the node syncing
47pub is_syncing: bool,
48/// Should this node have any peers
49 ///
50 /// Might be false for local chains or when running without discovery.
51pub should_have_peers: bool,
52}
5354impl fmt::Display for Health {
55fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
56write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { "syncing" } else { "idle" })
57 }
58}
5960/// Network Peer information
61#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct PeerInfo<Hash, Number> {
64/// Peer ID
65pub peer_id: String,
66/// Roles
67pub roles: String,
68/// Peer best block hash
69pub best_hash: Hash,
70/// Peer best block number
71pub best_number: Number,
72}
7374/// The role the node is running as
75#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
76pub enum NodeRole {
77/// The node is a full node
78Full,
79/// The node is an authority
80Authority,
81}
8283/// The state of the syncing of the node.
84#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
85#[serde(rename_all = "camelCase")]
86pub struct SyncState<Number> {
87/// Height of the block at which syncing started.
88pub starting_block: Number,
89/// Height of the current best block of the node.
90pub current_block: Number,
91/// Height of the highest block in the network.
92pub highest_block: Number,
93}
9495#[cfg(test)]
96mod tests {
97use super::*;
9899#[test]
100fn should_serialize_health() {
101assert_eq!(
102 ::serde_json::to_string(&Health {
103 peers: 1,
104 is_syncing: false,
105 should_have_peers: true,
106 })
107 .unwrap(),
108r#"{"peers":1,"isSyncing":false,"shouldHavePeers":true}"#,
109 );
110 }
111112#[test]
113fn should_serialize_peer_info() {
114assert_eq!(
115 ::serde_json::to_string(&PeerInfo {
116 peer_id: "2".into(),
117 roles: "a".into(),
118 best_hash: 5u32,
119 best_number: 6u32,
120 })
121 .unwrap(),
122r#"{"peerId":"2","roles":"a","bestHash":5,"bestNumber":6}"#,
123 );
124 }
125126#[test]
127fn should_serialize_sync_state() {
128assert_eq!(
129 ::serde_json::to_string(&SyncState {
130 starting_block: 12u32,
131 current_block: 50u32,
132 highest_block: 128u32,
133 })
134 .unwrap(),
135r#"{"startingBlock":12,"currentBlock":50,"highestBlock":128}"#,
136 );
137138assert_eq!(
139 ::serde_json::to_string(&SyncState {
140 starting_block: 12u32,
141 current_block: 50u32,
142 highest_block: 50u32,
143 })
144 .unwrap(),
145r#"{"startingBlock":12,"currentBlock":50,"highestBlock":50}"#,
146 );
147 }
148}