Skip to content

Commit 552f221

Browse files
committed
remove json-rpc from trin-cli
1 parent 6c7f801 commit 552f221

File tree

1 file changed

+1
-172
lines changed

1 file changed

+1
-172
lines changed

trin-cli/src/main.rs

Lines changed: 1 addition & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
pub mod dashboard;
22
use clap::{Args, Parser, Subcommand};
33

4-
#[cfg(unix)]
5-
use std::os::unix::net::UnixStream;
6-
#[cfg(windows)]
7-
use uds_windows::UnixStream;
8-
9-
use std::path::{Path, PathBuf};
4+
use std::path::Path;
105

116
use ethereum_types::H256;
12-
use serde_json::value::RawValue;
137
use thiserror::Error;
148

159
use dashboard::grafana::{GrafanaAPI, DASHBOARD_TEMPLATES};
1610
use ethportal_api::{BlockBodyKey, BlockHeaderKey, BlockReceiptsKey, HistoryContentKey};
17-
use trin_types::cli::DEFAULT_WEB3_IPC_PATH;
1811
use trin_utils::bytes::hex_encode;
1912

2013
#[derive(Parser, Debug, PartialEq)]
@@ -25,28 +18,11 @@ use trin_utils::bytes::hex_encode;
2518
about = "Portal Network command line utilities"
2619
)]
2720
enum Trin {
28-
JsonRpc(JsonRpc),
2921
#[command(subcommand)]
3022
EncodeKey(EncodeKey),
3123
CreateDashboard(DashboardConfig),
3224
}
3325

34-
#[derive(Args, Debug, PartialEq)]
35-
#[command(name = "json-rpc", about = "Run JSON-RPC commands against a trin node")]
36-
struct JsonRpc {
37-
/// IPC path of target JSON-RPC endpoint.
38-
#[arg(default_value = DEFAULT_WEB3_IPC_PATH, long)]
39-
ipc: PathBuf,
40-
41-
/// JSON-RPC method (e.g. discv5_routingTableInfo).
42-
#[arg(required = true)]
43-
endpoint: String,
44-
45-
/// Comma-separated list of JSON-RPC parameters.
46-
#[arg(long, value_delimiter = ',')]
47-
params: Option<Vec<String>>,
48-
}
49-
5026
// TODO: Remove clippy allow once a variant with non-"Block" prefix is added.
5127
/// Encode a content key.
5228
#[derive(Subcommand, Debug, PartialEq)]
@@ -91,32 +67,11 @@ struct DashboardConfig {
9167

9268
fn main() -> Result<(), Box<dyn std::error::Error>> {
9369
match Trin::parse() {
94-
Trin::JsonRpc(rpc) => json_rpc(rpc),
9570
Trin::EncodeKey(content_key) => encode_content_key(content_key),
9671
Trin::CreateDashboard(dashboard_config) => create_dashboard(dashboard_config),
9772
}
9873
}
9974

100-
fn json_rpc(rpc: JsonRpc) -> Result<(), Box<dyn std::error::Error>> {
101-
let params: Option<Vec<Box<RawValue>>> = rpc
102-
.params
103-
.map(|param| param.into_iter().map(jsonrpc::arg).collect());
104-
eprintln!(
105-
"Attempting RPC. endpoint={} params={:?} file={}",
106-
rpc.endpoint,
107-
params,
108-
rpc.ipc.to_string_lossy()
109-
);
110-
let mut client = TrinClient::from_ipc(&rpc.ipc)?;
111-
112-
let req = client.build_request(rpc.endpoint.as_str(), &params);
113-
let resp = client.make_request(req)?;
114-
115-
println!("{}", serde_json::to_string_pretty(&resp).unwrap());
116-
117-
Ok(())
118-
}
119-
12075
fn encode_content_key(content_key: EncodeKey) -> Result<(), Box<dyn std::error::Error>> {
12176
let key = match content_key {
12277
EncodeKey::BlockHeader { block_hash } => {
@@ -161,137 +116,11 @@ fn create_dashboard(dashboard_config: DashboardConfig) -> Result<(), Box<dyn std
161116
Ok(())
162117
}
163118

164-
fn build_request<'a>(
165-
method: &'a str,
166-
raw_params: &'a Option<Vec<Box<RawValue>>>,
167-
request_id: u64,
168-
) -> jsonrpc::Request<'a> {
169-
match raw_params {
170-
Some(val) => jsonrpc::Request {
171-
method,
172-
params: val,
173-
id: serde_json::json!(request_id),
174-
jsonrpc: Some("2.0"),
175-
},
176-
None => jsonrpc::Request {
177-
method,
178-
params: &[],
179-
id: serde_json::json!(request_id),
180-
jsonrpc: Some("2.0"),
181-
},
182-
}
183-
}
184-
185-
pub trait TryClone {
186-
fn try_clone(&self) -> std::io::Result<Self>
187-
where
188-
Self: Sized;
189-
}
190-
191-
impl TryClone for UnixStream {
192-
fn try_clone(&self) -> std::io::Result<Self> {
193-
UnixStream::try_clone(self)
194-
}
195-
}
196-
197-
pub struct TrinClient<S>
198-
where
199-
S: std::io::Read + std::io::Write + TryClone,
200-
{
201-
stream: S,
202-
request_id: u64,
203-
}
204-
205-
impl TrinClient<UnixStream> {
206-
fn from_ipc(path: &Path) -> std::io::Result<Self> {
207-
// TODO: a nice error if this file does not exist
208-
Ok(Self {
209-
stream: UnixStream::connect(path)?,
210-
request_id: 0,
211-
})
212-
}
213-
}
214-
215-
#[derive(Error, Debug)]
216-
pub enum JsonRpcError {
217-
#[error("Received malformed response: {0}")]
218-
Malformed(serde_json::Error),
219-
220-
#[error("Received empty response")]
221-
Empty,
222-
}
223-
224-
// TryClone is used because JSON-RPC responses are not followed by EOF. We must read bytes
225-
// from the stream until a complete object is detected, and the simplest way of doing that
226-
// with available APIs is to give ownership of a Read to a serde_json::Deserializer. If we
227-
// gave it exclusive ownership that would require us to open a new connection for every
228-
// command we wanted to send! By making a clone (or, by trying to) we can have our cake
229-
// and eat it too.
230-
//
231-
// TryClone is not necessary if TrinClient stays in this file forever; this script only
232-
// needs to make a single request before it exits. However, in a future where TrinClient
233-
// becomes the mechanism other parts of the codebase (such as peertester) use to act as
234-
// JSON-RPC clients then this becomes necessary. So, this is slightly over-engineered but
235-
// with an eye to future growth.
236-
impl<'a, S> TrinClient<S>
237-
where
238-
S: std::io::Read + std::io::Write + TryClone,
239-
{
240-
fn build_request(
241-
&mut self,
242-
method: &'a str,
243-
params: &'a Option<Vec<Box<RawValue>>>,
244-
) -> jsonrpc::Request<'a> {
245-
let result = build_request(method, params, self.request_id);
246-
self.request_id += 1;
247-
248-
result
249-
}
250-
251-
fn make_request(&mut self, req: jsonrpc::Request) -> Result<serde_json::Value, JsonRpcError> {
252-
let data = serde_json::to_vec(&req).unwrap();
253-
254-
self.stream.write_all(&data).unwrap();
255-
self.stream.flush().unwrap();
256-
257-
let clone = self.stream.try_clone().unwrap();
258-
let deser = serde_json::Deserializer::from_reader(clone);
259-
260-
if let Some(obj) = deser.into_iter::<serde_json::Value>().next() {
261-
return obj.map_err(JsonRpcError::Malformed);
262-
}
263-
264-
// this should only happen when they immediately send EOF
265-
Err(JsonRpcError::Empty)
266-
}
267-
}
268-
269119
#[cfg(test)]
270120
mod tests {
271121
use super::*;
272122
use std::str::FromStr;
273123

274-
#[test]
275-
fn test_trin_with_json_rpc() {
276-
let trin = Trin::parse_from([
277-
"test",
278-
"json-rpc",
279-
"--ipc",
280-
"/tmp/trin.ipc",
281-
"--params",
282-
"p1,p2",
283-
"discv5_routingTableInfo",
284-
]);
285-
assert_eq!(
286-
trin,
287-
Trin::JsonRpc(JsonRpc {
288-
ipc: PathBuf::from("/tmp/trin.ipc"),
289-
endpoint: "discv5_routingTableInfo".to_string(),
290-
params: Some(vec!["p1".to_string(), "p2".to_string()]),
291-
})
292-
);
293-
}
294-
295124
#[test]
296125
fn test_trin_with_encode_key() {
297126
const BLOCK_HASH: &str =

0 commit comments

Comments
 (0)