1#[cfg(test)]
22mod tests;
23
24use 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};
33
34pub use self::helpers::{Health, NodeRole, PeerInfo, SyncState, SystemInfo};
35pub use sc_rpc_api::system::*;
36
37pub struct System<B: traits::Block> {
39 info: SystemInfo,
40 send_back: TracingUnboundedSender<Request<B>>,
41}
42
43pub enum Request<B: traits::Block> {
45 Health(oneshot::Sender<Health>),
47 LocalPeerId(oneshot::Sender<String>),
49 LocalListenAddresses(oneshot::Sender<Vec<String>>),
52 Peers(oneshot::Sender<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>>),
54 NetworkState(oneshot::Sender<serde_json::Value>),
56 NetworkAddReservedPeer(String, oneshot::Sender<error::Result<()>>),
58 NetworkRemoveReservedPeer(String, oneshot::Sender<error::Result<()>>),
60 NetworkReservedPeers(oneshot::Sender<Vec<String>>),
62 NodeRoles(oneshot::Sender<Vec<NodeRole>>),
64 SyncState(oneshot::Sender<SyncState<<B::Header as HeaderT>::Number>>),
66}
67
68impl<B: traits::Block> System<B> {
69 pub fn new(info: SystemInfo, send_back: TracingUnboundedSender<Request<B>>) -> Self {
74 System { info, send_back }
75 }
76}
77
78#[async_trait]
79impl<B: traits::Block> SystemApiServer<B::Hash, <B::Header as HeaderT>::Number> for System<B> {
80 fn system_name(&self) -> Result<String, Error> {
81 Ok(self.info.impl_name.clone())
82 }
83
84 fn system_version(&self) -> Result<String, Error> {
85 Ok(self.info.impl_version.clone())
86 }
87
88 fn system_chain(&self) -> Result<String, Error> {
89 Ok(self.info.chain_name.clone())
90 }
91
92 fn system_type(&self) -> Result<sc_chain_spec::ChainType, Error> {
93 Ok(self.info.chain_type.clone())
94 }
95
96 fn system_properties(&self) -> Result<sc_chain_spec::Properties, Error> {
97 Ok(self.info.properties.clone())
98 }
99
100 async fn system_health(&self) -> Result<Health, Error> {
101 let (tx, rx) = oneshot::channel();
102 let _ = self.send_back.unbounded_send(Request::Health(tx));
103 rx.await.map_err(|e| Error::Internal(e.to_string()))
104 }
105
106 async fn system_local_peer_id(&self) -> Result<String, Error> {
107 let (tx, rx) = oneshot::channel();
108 let _ = self.send_back.unbounded_send(Request::LocalPeerId(tx));
109 rx.await.map_err(|e| Error::Internal(e.to_string()))
110 }
111
112 async fn system_local_listen_addresses(&self) -> Result<Vec<String>, Error> {
113 let (tx, rx) = oneshot::channel();
114 let _ = self.send_back.unbounded_send(Request::LocalListenAddresses(tx));
115 rx.await.map_err(|e| Error::Internal(e.to_string()))
116 }
117
118 async 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)?;
123 let (tx, rx) = oneshot::channel();
124 let _ = self.send_back.unbounded_send(Request::Peers(tx));
125 rx.await.map_err(|e| Error::Internal(e.to_string()))
126 }
127
128 async fn system_network_state(&self, ext: &Extensions) -> Result<JsonValue, Error> {
129 check_if_safe(ext)?;
130 let (tx, rx) = oneshot::channel();
131 let _ = self.send_back.unbounded_send(Request::NetworkState(tx));
132 rx.await.map_err(|e| Error::Internal(e.to_string()))
133 }
134
135 async fn system_add_reserved_peer(&self, ext: &Extensions, peer: String) -> Result<(), Error> {
136 check_if_safe(ext)?;
137 let (tx, rx) = oneshot::channel();
138 let _ = self.send_back.unbounded_send(Request::NetworkAddReservedPeer(peer, tx));
139 match rx.await {
140 Ok(Ok(())) => Ok(()),
141 Ok(Err(e)) => Err(e),
142 Err(e) => Err(Error::Internal(e.to_string())),
143 }
144 }
145
146 async fn system_remove_reserved_peer(
147 &self,
148 ext: &Extensions,
149 peer: String,
150 ) -> Result<(), Error> {
151 check_if_safe(ext)?;
152 let (tx, rx) = oneshot::channel();
153 let _ = self.send_back.unbounded_send(Request::NetworkRemoveReservedPeer(peer, tx));
154 match rx.await {
155 Ok(Ok(())) => Ok(()),
156 Ok(Err(e)) => Err(e),
157 Err(e) => Err(Error::Internal(e.to_string())),
158 }
159 }
160
161 async fn system_reserved_peers(&self) -> Result<Vec<String>, Error> {
162 let (tx, rx) = oneshot::channel();
163 let _ = self.send_back.unbounded_send(Request::NetworkReservedPeers(tx));
164 rx.await.map_err(|e| Error::Internal(e.to_string()))
165 }
166
167 async fn system_node_roles(&self) -> Result<Vec<NodeRole>, Error> {
168 let (tx, rx) = oneshot::channel();
169 let _ = self.send_back.unbounded_send(Request::NodeRoles(tx));
170 rx.await.map_err(|e| Error::Internal(e.to_string()))
171 }
172
173 async fn system_sync_state(&self) -> Result<SyncState<<B::Header as HeaderT>::Number>, Error> {
174 let (tx, rx) = oneshot::channel();
175 let _ = self.send_back.unbounded_send(Request::SyncState(tx));
176 rx.await.map_err(|e| Error::Internal(e.to_string()))
177 }
178
179 fn system_add_log_filter(&self, ext: &Extensions, directives: String) -> Result<(), Error> {
180 check_if_safe(ext)?;
181
182 logging::add_directives(&directives);
183 logging::reload_filter().map_err(|e| Error::Internal(e))
184 }
185
186 fn 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}