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.
2021#[cfg(test)]
22mod tests;
2324use futures::channel::oneshot;
25use jsonrpsee::{
26 core::{async_trait, JsonValue},
27 Extensions,
28};
29use sc_rpc_api::check_if_safe;
30use sc_tracing::logging;
31use sc_utils::mpsc::TracingUnboundedSender;
32use sp_runtime::traits::{self, Header as HeaderT};
3334pub use self::helpers::{Health, NodeRole, PeerInfo, SyncState, SystemInfo};
35pub use sc_rpc_api::system::*;
3637/// System API implementation
38pub struct System<B: traits::Block> {
39 info: SystemInfo,
40 send_back: TracingUnboundedSender<Request<B>>,
41}
4243/// Request to be processed.
44pub enum Request<B: traits::Block> {
45/// Must return the health of the network.
46Health(oneshot::Sender<Health>),
47/// Must return the base58-encoded local `PeerId`.
48LocalPeerId(oneshot::Sender<String>),
49/// Must return the string representation of the addresses we listen on, including the
50 /// trailing `/p2p/`.
51LocalListenAddresses(oneshot::Sender<Vec<String>>),
52/// Must return information about the peers we are connected to.
53Peers(oneshot::Sender<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>>),
54/// Must return the state of the network.
55NetworkState(oneshot::Sender<serde_json::Value>),
56/// Must return any potential parse error.
57NetworkAddReservedPeer(String, oneshot::Sender<error::Result<()>>),
58/// Must return any potential parse error.
59NetworkRemoveReservedPeer(String, oneshot::Sender<error::Result<()>>),
60/// Must return the list of reserved peers
61NetworkReservedPeers(oneshot::Sender<Vec<String>>),
62/// Must return the node role.
63NodeRoles(oneshot::Sender<Vec<NodeRole>>),
64/// Must return the state of the node syncing.
65SyncState(oneshot::Sender<SyncState<<B::Header as HeaderT>::Number>>),
66}
6768impl<B: traits::Block> System<B> {
69/// Creates new `System`.
70 ///
71 /// The `send_back` will be used to transmit some of the requests. The user is responsible for
72 /// reading from that channel and answering the requests.
73pub fn new(info: SystemInfo, send_back: TracingUnboundedSender<Request<B>>) -> Self {
74 System { info, send_back }
75 }
76}
7778#[async_trait]
79impl<B: traits::Block> SystemApiServer<B::Hash, <B::Header as HeaderT>::Number> for System<B> {
80fn system_name(&self) -> Result<String, Error> {
81Ok(self.info.impl_name.clone())
82 }
8384fn system_version(&self) -> Result<String, Error> {
85Ok(self.info.impl_version.clone())
86 }
8788fn system_chain(&self) -> Result<String, Error> {
89Ok(self.info.chain_name.clone())
90 }
9192fn system_type(&self) -> Result<sc_chain_spec::ChainType, Error> {
93Ok(self.info.chain_type.clone())
94 }
9596fn system_properties(&self) -> Result<sc_chain_spec::Properties, Error> {
97Ok(self.info.properties.clone())
98 }
99100async fn system_health(&self) -> Result<Health, Error> {
101let (tx, rx) = oneshot::channel();
102let _ = self.send_back.unbounded_send(Request::Health(tx));
103 rx.await.map_err(|e| Error::Internal(e.to_string()))
104 }
105106async fn system_local_peer_id(&self) -> Result<String, Error> {
107let (tx, rx) = oneshot::channel();
108let _ = self.send_back.unbounded_send(Request::LocalPeerId(tx));
109 rx.await.map_err(|e| Error::Internal(e.to_string()))
110 }
111112async fn system_local_listen_addresses(&self) -> Result<Vec<String>, Error> {
113let (tx, rx) = oneshot::channel();
114let _ = self.send_back.unbounded_send(Request::LocalListenAddresses(tx));
115 rx.await.map_err(|e| Error::Internal(e.to_string()))
116 }
117118async fn system_peers(
119&self,
120 ext: &Extensions,
121 ) -> Result<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>, Error> {
122 check_if_safe(ext)?;
123let (tx, rx) = oneshot::channel();
124let _ = self.send_back.unbounded_send(Request::Peers(tx));
125 rx.await.map_err(|e| Error::Internal(e.to_string()))
126 }
127128async fn system_network_state(&self, ext: &Extensions) -> Result<JsonValue, Error> {
129 check_if_safe(ext)?;
130let (tx, rx) = oneshot::channel();
131let _ = self.send_back.unbounded_send(Request::NetworkState(tx));
132 rx.await.map_err(|e| Error::Internal(e.to_string()))
133 }
134135async fn system_add_reserved_peer(&self, ext: &Extensions, peer: String) -> Result<(), Error> {
136 check_if_safe(ext)?;
137let (tx, rx) = oneshot::channel();
138let _ = self.send_back.unbounded_send(Request::NetworkAddReservedPeer(peer, tx));
139match rx.await {
140Ok(Ok(())) => Ok(()),
141Ok(Err(e)) => Err(e),
142Err(e) => Err(Error::Internal(e.to_string())),
143 }
144 }
145146async fn system_remove_reserved_peer(
147&self,
148 ext: &Extensions,
149 peer: String,
150 ) -> Result<(), Error> {
151 check_if_safe(ext)?;
152let (tx, rx) = oneshot::channel();
153let _ = self.send_back.unbounded_send(Request::NetworkRemoveReservedPeer(peer, tx));
154match rx.await {
155Ok(Ok(())) => Ok(()),
156Ok(Err(e)) => Err(e),
157Err(e) => Err(Error::Internal(e.to_string())),
158 }
159 }
160161async fn system_reserved_peers(&self) -> Result<Vec<String>, Error> {
162let (tx, rx) = oneshot::channel();
163let _ = self.send_back.unbounded_send(Request::NetworkReservedPeers(tx));
164 rx.await.map_err(|e| Error::Internal(e.to_string()))
165 }
166167async fn system_node_roles(&self) -> Result<Vec<NodeRole>, Error> {
168let (tx, rx) = oneshot::channel();
169let _ = self.send_back.unbounded_send(Request::NodeRoles(tx));
170 rx.await.map_err(|e| Error::Internal(e.to_string()))
171 }
172173async fn system_sync_state(&self) -> Result<SyncState<<B::Header as HeaderT>::Number>, Error> {
174let (tx, rx) = oneshot::channel();
175let _ = self.send_back.unbounded_send(Request::SyncState(tx));
176 rx.await.map_err(|e| Error::Internal(e.to_string()))
177 }
178179fn system_add_log_filter(&self, ext: &Extensions, directives: String) -> Result<(), Error> {
180 check_if_safe(ext)?;
181182 logging::add_directives(&directives);
183 logging::reload_filter().map_err(|e| Error::Internal(e))
184 }
185186fn system_reset_log_filter(&self, ext: &Extensions) -> Result<(), Error> {
187 check_if_safe(ext)?;
188 logging::reset_log_filter().map_err(|e| Error::Internal(e))
189 }
190}