// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Substrate is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . //! Substrate system API. #[cfg(test)] mod tests; use futures::{future::BoxFuture, FutureExt, TryFutureExt}; use futures::{channel::oneshot, compat::Compat}; use sc_rpc_api::Receiver; use sp_utils::mpsc::TracingUnboundedSender; use sp_runtime::traits::{self, Header as HeaderT}; use self::error::Result; pub use sc_rpc_api::system::*; pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; /// System API implementation pub struct System { info: SystemInfo, send_back: TracingUnboundedSender>, } /// Request to be processed. pub enum Request { /// Must return the health of the network. Health(oneshot::Sender), /// Must return information about the peers we are connected to. Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. NetworkState(oneshot::Sender), /// Must return any potential parse error. NetworkAddReservedPeer(String, oneshot::Sender>), /// Must return any potential parse error. NetworkRemoveReservedPeer(String, oneshot::Sender>), /// Must return the node role. NodeRoles(oneshot::Sender>) } impl System { /// Creates new `System`. /// /// The `send_back` will be used to transmit some of the requests. The user is responsible for /// reading from that channel and answering the requests. pub fn new( info: SystemInfo, send_back: TracingUnboundedSender>, ) -> Self { System { info, send_back, } } } impl SystemApi::Number> for System { fn system_name(&self) -> Result { Ok(self.info.impl_name.clone()) } fn system_version(&self) -> Result { Ok(self.info.impl_version.clone()) } fn system_chain(&self) -> Result { Ok(self.info.chain_name.clone()) } fn system_properties(&self) -> Result { Ok(self.info.properties.clone()) } fn system_health(&self) -> Receiver { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::Health(tx)); Receiver(Compat::new(rx)) } fn system_peers(&self) -> Receiver::Number>>> { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::Peers(tx)); Receiver(Compat::new(rx)) } fn system_network_state(&self) -> Receiver { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkState(tx)); Receiver(Compat::new(rx)) } fn system_add_reserved_peer(&self, peer: String) -> Compat>> { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkAddReservedPeer(peer, tx)); async move { match rx.await { Ok(Ok(())) => Ok(()), Ok(Err(e)) => Err(rpc::Error::from(e)), Err(_) => Err(rpc::Error::internal_error()), } }.boxed().compat() } fn system_remove_reserved_peer(&self, peer: String) -> Compat>> { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkRemoveReservedPeer(peer, tx)); async move { match rx.await { Ok(Ok(())) => Ok(()), Ok(Err(e)) => Err(rpc::Error::from(e)), Err(_) => Err(rpc::Error::internal_error()), } }.boxed().compat() } fn system_node_roles(&self) -> Receiver> { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NodeRoles(tx)); Receiver(Compat::new(rx)) } }