Skip to content

Commit 297f590

Browse files
kakao-jun-ejoojis
authored andcommitted
Add IPC support to JSON RPC
1 parent 2ec23e7 commit 297f590

File tree

8 files changed

+214
-22
lines changed

8 files changed

+214
-22
lines changed

Cargo.lock

Lines changed: 138 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codechain/codechain.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ args:
6767
help: Listen for rpc connections on PORT.
6868
takes_value: true
6969
default_value: "8080"
70+
- ipc-path:
71+
long: ipc-path
72+
value_name: path
73+
help: Specify custom path for JSON-RPC over IPC service.
74+
takes_value: true
75+
default_value: "/tmp/jsonrpc.ipc"
7076
- no-jsonrpc:
7177
long: no-jsonrpc
7278
help: Do not run jsonrpc.

codechain/config/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use cdiscovery::{KademliaConfig, UnstructuredConfig};
2222
use clap;
2323
use cnetwork::{NetworkConfig, SocketAddr};
2424
use ctypes::{Address, Secret};
25-
use rpc::HttpConfiguration as RpcHttpConfig;
25+
use rpc::{HttpConfiguration as RpcHttpConfig, IpcConfiguration as RpcIpcConfig};
2626
use toml;
2727

2828
#[derive(Debug, PartialEq, Deserialize)]
@@ -221,3 +221,15 @@ pub fn parse_rpc_config(matches: &clap::ArgMatches) -> Result<Option<RpcHttpConf
221221

222222
Ok(Some(config))
223223
}
224+
225+
pub fn parse_rpc_ipc_config(matches: &clap::ArgMatches) -> Result<Option<RpcIpcConfig>, String> {
226+
if matches.is_present("no-jsonrpc") {
227+
return Ok(None)
228+
}
229+
230+
let socket_addr = value_t_or_exit!(matches, "ipc-path", String);
231+
232+
Ok(Some(RpcIpcConfig {
233+
socket_addr,
234+
}))
235+
}

codechain/main.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ use clap::ArgMatches;
6363
use clogger::LoggerConfig;
6464
use cnetwork::{NetworkConfig, NetworkService, SocketAddr};
6565
use creactor::EventLoop;
66-
use crpc::Server as RpcServer;
66+
use crpc::{HttpServer, IpcServer};
6767
use csync::{BlockSyncExtension, ParcelSyncExtension, SnapshotService};
6868
use ctrlc::CtrlC;
6969
use fdlimit::raise_fd_limit;
7070
use parking_lot::{Condvar, Mutex};
71-
use rpc::HttpConfiguration as RpcHttpConfig;
71+
use rpc::{HttpConfiguration as RpcHttpConfig, IpcConfiguration as RpcIpcConfig};
7272

7373
#[cfg(feature = "stratum")]
7474
extern crate stratum;
@@ -80,11 +80,16 @@ pub const APP_INFO: AppInfo = AppInfo {
8080
author: "Kodebox",
8181
};
8282

83-
pub fn rpc_start(cfg: RpcHttpConfig, deps: Arc<rpc_apis::ApiDependencies>) -> Result<RpcServer, String> {
83+
pub fn rpc_start(cfg: RpcHttpConfig, deps: Arc<rpc_apis::ApiDependencies>) -> Result<HttpServer, String> {
8484
info!("RPC Listening on {}", cfg.port);
8585
rpc::new_http(cfg, deps)
8686
}
8787

88+
pub fn rpc_ipc_start(cfg: RpcIpcConfig, deps: Arc<rpc_apis::ApiDependencies>) -> Result<IpcServer, String> {
89+
info!("IPC Listening on {}", cfg.socket_addr);
90+
rpc::new_ipc(cfg, deps)
91+
}
92+
8893
pub fn network_start(cfg: &NetworkConfig) -> Result<NetworkService, String> {
8994
info!("Handshake Listening on {}", cfg.port);
9095
let address = SocketAddr::v4(127, 0, 0, 1, cfg.port);
@@ -182,6 +187,14 @@ fn run_node(matches: ArgMatches) -> Result<(), String> {
182187
}
183188
};
184189

190+
let _ipc_server = {
191+
if let Some(rpc_ipcconfig) = config::parse_rpc_ipc_config(&matches)? {
192+
Some(rpc_ipc_start(rpc_ipcconfig, rpc_apis_deps.clone())?)
193+
} else {
194+
None
195+
}
196+
};
197+
185198
let _network_service = {
186199
if let Some(network_config) = config::parse_network_config(&matches)? {
187200
let service = network_start(&network_config)?;

codechain/rpc.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use std::io;
1818
use std::net::SocketAddr;
1919
use std::sync::Arc;
2020

21-
use crpc::{start_http, Compatibility, MetaIoHandler, Server};
21+
use crpc::{start_http, start_ipc, HttpServer, IpcServer};
22+
use crpc::{Compatibility, MetaIoHandler};
2223
use rpc_apis;
2324

2425
#[derive(Debug, PartialEq)]
@@ -40,7 +41,7 @@ impl HttpConfiguration {
4041
}
4142
}
4243

43-
pub fn new_http(cfg: HttpConfiguration, deps: Arc<rpc_apis::ApiDependencies>) -> Result<Server, String> {
44+
pub fn new_http(cfg: HttpConfiguration, deps: Arc<rpc_apis::ApiDependencies>) -> Result<HttpServer, String> {
4445
let url = format!("{}:{}", cfg.interface, cfg.port);
4546
let addr = url.parse().map_err(|_| format!("Invalid JSONRPC listen host/port given: {}", url))?;
4647
let server = setup_http_rpc_server(&addr, cfg.cors, cfg.hosts, deps)?;
@@ -52,7 +53,7 @@ pub fn setup_http_rpc_server(
5253
cors_domains: Option<Vec<String>>,
5354
allowed_hosts: Option<Vec<String>>,
5455
deps: Arc<rpc_apis::ApiDependencies>,
55-
) -> Result<Server, String> {
56+
) -> Result<HttpServer, String> {
5657
let server = setup_rpc_server(deps);
5758
let start_result = start_http(url, cors_domains, allowed_hosts, server);
5859
match start_result {
@@ -64,6 +65,23 @@ pub fn setup_http_rpc_server(
6465
}
6566
}
6667

68+
#[derive(Debug, PartialEq)]
69+
pub struct IpcConfiguration {
70+
pub socket_addr: String,
71+
}
72+
73+
pub fn new_ipc(cfg: IpcConfiguration, deps: Arc<rpc_apis::ApiDependencies>) -> Result<IpcServer, String> {
74+
let server = setup_rpc_server(deps);
75+
let start_result = start_ipc(&cfg.socket_addr, server);
76+
match start_result {
77+
Err(ref err) if err.kind() == io::ErrorKind::AddrInUse => {
78+
Err(format!("IPC address {} is already in use, make sure that another instance of a Codechain node is not running or change the address using the --ipc-path options.", cfg.socket_addr))
79+
},
80+
Err(e) => Err(format!("IPC error: {:?}", e)),
81+
Ok(server) => Ok(server),
82+
}
83+
}
84+
6785
fn setup_rpc_server(deps: Arc<rpc_apis::ApiDependencies>) -> MetaIoHandler<()> {
6886
let mut handler = MetaIoHandler::with_compatibility(Compatibility::Both);
6987
deps.extend_api(&mut handler);

rpc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ tokio-core = "0.1.1"
2121
jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git" }
2222
jsonrpc-macros = { git = "https://github.com/ethcore/jsonrpc.git" }
2323
jsonrpc-http-server = { git = "https://github.com/ethcore/jsonrpc.git" }
24+
jsonrpc-ipc-server = { git = "https://github.com/ethcore/jsonrpc.git" }
2425

rpc/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extern crate codechain_core as ccore;
1818
extern crate codechain_types as ctypes;
1919
extern crate jsonrpc_core;
2020
extern crate jsonrpc_http_server;
21+
extern crate jsonrpc_ipc_server;
2122
extern crate kvdb;
2223
extern crate kvdb_rocksdb as rocksdb;
2324
extern crate log;
@@ -41,5 +42,8 @@ pub use rustc_serialize::hex;
4142
pub use jsonrpc_core::{Compatibility, Error, MetaIoHandler, Params, Value};
4243
pub use jsonrpc_http_server::tokio_core::reactor::Remote;
4344

44-
pub use jsonrpc_http_server::Server;
45+
pub use jsonrpc_http_server::Server as HttpServer;
4546
pub use rpc_server::start_http;
47+
48+
pub use jsonrpc_ipc_server::Server as IpcServer;
49+
pub use rpc_server::start_ipc;

rpc/src/rpc_server.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
// TODO: panic handler
1818
use jsonrpc_core;
19-
use jsonrpc_http_server::{self, Host, Server, ServerBuilder};
19+
use jsonrpc_http_server::{self, Host, Server as HttpServer, ServerBuilder as HttpServerBuilder};
20+
use jsonrpc_ipc_server::{Server as IpcServer, ServerBuilder as IpcServerBuilder};
2021
use std::default::Default;
2122
use std::io;
2223
use std::net::SocketAddr;
@@ -27,7 +28,7 @@ pub fn start_http<M: jsonrpc_core::Metadata>(
2728
cors_domains: Option<Vec<String>>,
2829
allowed_hosts: Option<Vec<String>>,
2930
handler: jsonrpc_core::MetaIoHandler<M>,
30-
) -> Result<Server, io::Error>
31+
) -> Result<HttpServer, io::Error>
3132
where
3233
M: Default, {
3334
let cors_domains = cors_domains.map(|domains| {
@@ -41,8 +42,18 @@ where
4142
.collect()
4243
});
4344

44-
ServerBuilder::new(handler)
45+
HttpServerBuilder::new(handler)
4546
.cors(cors_domains.into())
4647
.allowed_hosts(allowed_hosts.map(|hosts| hosts.into_iter().map(Host::from).collect()).into())
4748
.start_http(addr)
4849
}
50+
51+
/// Start ipc server asynchronously and returns result with `Server` handle on success or an error.
52+
pub fn start_ipc<M: jsonrpc_core::Metadata>(
53+
addr: &str,
54+
handler: jsonrpc_core::MetaIoHandler<M>,
55+
) -> Result<IpcServer, io::Error>
56+
where
57+
M: Default, {
58+
IpcServerBuilder::new(handler).start(addr)
59+
}

0 commit comments

Comments
 (0)