2016-12-07 05:14:52 -08:00
use std ::net ::SocketAddr ;
2016-12-12 10:18:43 -08:00
use std ::sync ::Arc ;
2016-12-07 05:14:52 -08:00
use rpc_apis ::{ self , ApiSet } ;
2016-12-20 02:51:50 -08:00
use ethcore_rpc ::{ Server , RpcServerError , start_http , MetaIoHandler , RpcHandler , Remote , Compatibility } ;
2016-12-12 10:49:01 -08:00
use network ::Magic ;
2016-12-07 05:14:52 -08:00
use std ::io ;
2016-12-07 11:39:12 -08:00
use sync ;
2016-12-12 10:49:01 -08:00
use db ;
2016-12-12 10:18:43 -08:00
use p2p ;
2016-12-07 11:39:12 -08:00
pub struct Dependencies {
2016-12-12 10:49:01 -08:00
pub network : Magic ,
2016-12-07 11:39:12 -08:00
pub local_sync_node : sync ::LocalNodeRef ,
2016-12-12 10:49:01 -08:00
pub storage : db ::SharedStore ,
2016-12-12 10:18:43 -08:00
pub p2p_context : Arc < p2p ::Context > ,
2016-12-20 02:42:51 -08:00
pub remote : Remote ,
2016-12-07 11:39:12 -08:00
}
2016-12-07 05:14:52 -08:00
#[ derive(Debug, PartialEq) ]
pub struct HttpConfiguration {
pub enabled : bool ,
pub interface : String ,
pub port : u16 ,
pub apis : ApiSet ,
pub cors : Option < Vec < String > > ,
pub hosts : Option < Vec < String > > ,
}
impl HttpConfiguration {
pub fn with_port ( port : u16 ) -> Self {
HttpConfiguration {
enabled : true ,
interface : " 127.0.0.1 " . into ( ) ,
port : port ,
apis : ApiSet ::default ( ) ,
cors : None ,
hosts : Some ( Vec ::new ( ) ) ,
}
}
}
2016-12-07 11:39:12 -08:00
pub fn new_http ( conf : HttpConfiguration , deps : Dependencies ) -> Result < Option < Server > , String > {
2016-12-07 05:14:52 -08:00
if ! conf . enabled {
return Ok ( None ) ;
}
let url = format! ( " {} : {} " , conf . interface , conf . port ) ;
let addr = try ! ( url . parse ( ) . map_err ( | _ | format! ( " Invalid JSONRPC listen host/port given: {} " , url ) ) ) ;
2016-12-07 11:39:12 -08:00
Ok ( Some ( try ! ( setup_http_rpc_server ( & addr , conf . cors , conf . hosts , conf . apis , deps ) ) ) )
2016-12-07 05:14:52 -08:00
}
pub fn setup_http_rpc_server (
url : & SocketAddr ,
cors_domains : Option < Vec < String > > ,
allowed_hosts : Option < Vec < String > > ,
2016-12-07 11:39:12 -08:00
apis : ApiSet ,
deps : Dependencies ,
2016-12-07 05:14:52 -08:00
) -> Result < Server , String > {
2016-12-20 02:42:51 -08:00
let remote = deps . remote . clone ( ) ;
let server = setup_rpc_server ( apis , deps ) ;
let handler = RpcHandler ::new ( Arc ::new ( server ) , remote ) ;
2016-12-07 05:14:52 -08:00
// TODO: PanicsHandler
2016-12-20 02:42:51 -08:00
let start_result = start_http ( url , cors_domains , allowed_hosts , handler ) ;
2016-12-07 05:14:52 -08:00
match start_result {
Err ( RpcServerError ::IoError ( err ) ) = > match err . kind ( ) {
io ::ErrorKind ::AddrInUse = > Err ( format! ( " RPC address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --jsonrpc-port and --jsonrpc-interface options. " , url ) ) ,
_ = > Err ( format! ( " RPC io error: {} " , err ) ) ,
} ,
Err ( e ) = > Err ( format! ( " RPC error: {:?} " , e ) ) ,
Ok ( server ) = > Ok ( server ) ,
}
}
2016-12-20 02:42:51 -08:00
fn setup_rpc_server ( apis : ApiSet , deps : Dependencies ) -> MetaIoHandler < ( ) > {
2016-12-20 02:51:50 -08:00
rpc_apis ::setup_rpc ( MetaIoHandler ::with_compatibility ( Compatibility ::Both ) , apis , deps )
2016-12-07 05:14:52 -08:00
}