1#[cfg(test)]
10mod tests;
11
12use crate::check_if_safe;
13use futures::channel::oneshot;
14use jsonrpsee::{
15 core::{async_trait, JsonValue},
16 Extensions,
17};
18use soil_client::tracing::logging;
19use soil_client::utils::mpsc::TracingUnboundedSender;
20use subsoil::runtime::traits::{self, Header as HeaderT};
21
22pub use self::helpers::{Health, NodeRole, PeerInfo, SyncState, SystemInfo};
23pub use crate::api::system::*;
24
25pub struct System<B: traits::Block> {
27 info: SystemInfo,
28 send_back: TracingUnboundedSender<Request<B>>,
29}
30
31pub enum Request<B: traits::Block> {
33 Health(oneshot::Sender<Health>),
35 LocalPeerId(oneshot::Sender<String>),
37 LocalListenAddresses(oneshot::Sender<Vec<String>>),
40 Peers(oneshot::Sender<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>>),
42 NetworkState(oneshot::Sender<serde_json::Value>),
44 NetworkAddReservedPeer(String, oneshot::Sender<error::Result<()>>),
46 NetworkRemoveReservedPeer(String, oneshot::Sender<error::Result<()>>),
48 NetworkReservedPeers(oneshot::Sender<Vec<String>>),
50 NodeRoles(oneshot::Sender<Vec<NodeRole>>),
52 SyncState(oneshot::Sender<SyncState<<B::Header as HeaderT>::Number>>),
54}
55
56impl<B: traits::Block> System<B> {
57 pub fn new(info: SystemInfo, send_back: TracingUnboundedSender<Request<B>>) -> Self {
62 System { info, send_back }
63 }
64}
65
66#[async_trait]
67impl<B: traits::Block> SystemApiServer<B::Hash, <B::Header as HeaderT>::Number> for System<B> {
68 fn system_name(&self) -> Result<String, Error> {
69 Ok(self.info.impl_name.clone())
70 }
71
72 fn system_version(&self) -> Result<String, Error> {
73 Ok(self.info.impl_version.clone())
74 }
75
76 fn system_chain(&self) -> Result<String, Error> {
77 Ok(self.info.chain_name.clone())
78 }
79
80 fn system_type(&self) -> Result<soil_chain_spec::ChainType, Error> {
81 Ok(self.info.chain_type.clone())
82 }
83
84 fn system_properties(&self) -> Result<soil_chain_spec::Properties, Error> {
85 Ok(self.info.properties.clone())
86 }
87
88 async fn system_health(&self) -> Result<Health, Error> {
89 let (tx, rx) = oneshot::channel();
90 let _ = self.send_back.unbounded_send(Request::Health(tx));
91 rx.await.map_err(|e| Error::Internal(e.to_string()))
92 }
93
94 async fn system_local_peer_id(&self) -> Result<String, Error> {
95 let (tx, rx) = oneshot::channel();
96 let _ = self.send_back.unbounded_send(Request::LocalPeerId(tx));
97 rx.await.map_err(|e| Error::Internal(e.to_string()))
98 }
99
100 async fn system_local_listen_addresses(&self) -> Result<Vec<String>, Error> {
101 let (tx, rx) = oneshot::channel();
102 let _ = self.send_back.unbounded_send(Request::LocalListenAddresses(tx));
103 rx.await.map_err(|e| Error::Internal(e.to_string()))
104 }
105
106 async fn system_peers(
107 &self,
108 ext: &Extensions,
109 ) -> Result<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>, Error> {
110 check_if_safe(ext)?;
111 let (tx, rx) = oneshot::channel();
112 let _ = self.send_back.unbounded_send(Request::Peers(tx));
113 rx.await.map_err(|e| Error::Internal(e.to_string()))
114 }
115
116 async fn system_network_state(&self, ext: &Extensions) -> Result<JsonValue, Error> {
117 check_if_safe(ext)?;
118 let (tx, rx) = oneshot::channel();
119 let _ = self.send_back.unbounded_send(Request::NetworkState(tx));
120 rx.await.map_err(|e| Error::Internal(e.to_string()))
121 }
122
123 async fn system_add_reserved_peer(&self, ext: &Extensions, peer: String) -> Result<(), Error> {
124 check_if_safe(ext)?;
125 let (tx, rx) = oneshot::channel();
126 let _ = self.send_back.unbounded_send(Request::NetworkAddReservedPeer(peer, tx));
127 match rx.await {
128 Ok(Ok(())) => Ok(()),
129 Ok(Err(e)) => Err(e),
130 Err(e) => Err(Error::Internal(e.to_string())),
131 }
132 }
133
134 async fn system_remove_reserved_peer(
135 &self,
136 ext: &Extensions,
137 peer: String,
138 ) -> Result<(), Error> {
139 check_if_safe(ext)?;
140 let (tx, rx) = oneshot::channel();
141 let _ = self.send_back.unbounded_send(Request::NetworkRemoveReservedPeer(peer, tx));
142 match rx.await {
143 Ok(Ok(())) => Ok(()),
144 Ok(Err(e)) => Err(e),
145 Err(e) => Err(Error::Internal(e.to_string())),
146 }
147 }
148
149 async fn system_reserved_peers(&self) -> Result<Vec<String>, Error> {
150 let (tx, rx) = oneshot::channel();
151 let _ = self.send_back.unbounded_send(Request::NetworkReservedPeers(tx));
152 rx.await.map_err(|e| Error::Internal(e.to_string()))
153 }
154
155 async fn system_node_roles(&self) -> Result<Vec<NodeRole>, Error> {
156 let (tx, rx) = oneshot::channel();
157 let _ = self.send_back.unbounded_send(Request::NodeRoles(tx));
158 rx.await.map_err(|e| Error::Internal(e.to_string()))
159 }
160
161 async fn system_sync_state(&self) -> Result<SyncState<<B::Header as HeaderT>::Number>, Error> {
162 let (tx, rx) = oneshot::channel();
163 let _ = self.send_back.unbounded_send(Request::SyncState(tx));
164 rx.await.map_err(|e| Error::Internal(e.to_string()))
165 }
166
167 fn system_add_log_filter(&self, ext: &Extensions, directives: String) -> Result<(), Error> {
168 check_if_safe(ext)?;
169
170 logging::add_directives(&directives);
171 logging::reload_filter().map_err(|e| Error::Internal(e))
172 }
173
174 fn system_reset_log_filter(&self, ext: &Extensions) -> Result<(), Error> {
175 check_if_safe(ext)?;
176 logging::reset_log_filter().map_err(|e| Error::Internal(e))
177 }
178}