@ -7,7 +7,7 @@ use std::fmt;
use std ::fs ;
use std ::fs ;
use std ::net ::SocketAddr ;
use std ::net ::SocketAddr ;
use std ::net ::ToSocketAddrs ;
use std ::net ::ToSocketAddrs ;
use std ::path ::PathBuf ;
use std ::path ::{ Path , PathBuf } ;
use std ::str ::FromStr ;
use std ::str ::FromStr ;
use std ::sync ::Arc ;
use std ::sync ::Arc ;
use stderrlog ;
use stderrlog ;
@ -121,7 +121,6 @@ impl Into<Network> for BitcoinNetwork {
}
}
/// Parsed and post-processed configuration
/// Parsed and post-processed configuration
#[ derive(Debug) ]
pub struct Config {
pub struct Config {
// See below for the documentation of each field:
// See below for the documentation of each field:
pub log : stderrlog ::StdErrLog ,
pub log : stderrlog ::StdErrLog ,
@ -129,7 +128,6 @@ pub struct Config {
pub db_path : PathBuf ,
pub db_path : PathBuf ,
pub daemon_dir : PathBuf ,
pub daemon_dir : PathBuf ,
pub daemon_rpc_addr : SocketAddr ,
pub daemon_rpc_addr : SocketAddr ,
pub cookie : Option < String > ,
pub electrum_rpc_addr : SocketAddr ,
pub electrum_rpc_addr : SocketAddr ,
pub monitoring_addr : SocketAddr ,
pub monitoring_addr : SocketAddr ,
pub jsonrpc_import : bool ,
pub jsonrpc_import : bool ,
@ -139,6 +137,7 @@ pub struct Config {
pub txid_limit : usize ,
pub txid_limit : usize ,
pub server_banner : String ,
pub server_banner : String ,
pub blocktxids_cache_size : usize ,
pub blocktxids_cache_size : usize ,
pub cookie_getter : Arc < dyn CookieGetter > ,
}
}
/// Returns default daemon directory
/// Returns default daemon directory
@ -151,6 +150,22 @@ fn default_daemon_dir() -> PathBuf {
home
home
}
}
fn create_cookie_getter (
cookie : Option < String > ,
cookie_file : Option < PathBuf > ,
daemon_dir : & Path ,
) -> Arc < dyn CookieGetter > {
match ( cookie , cookie_file ) {
( None , None ) = > Arc ::new ( CookieFile ::from_daemon_dir ( daemon_dir ) ) ,
( None , Some ( file ) ) = > Arc ::new ( CookieFile ::from_file ( file ) ) ,
( Some ( cookie ) , None ) = > Arc ::new ( StaticCookie ::from_string ( cookie ) ) ,
( Some ( _ ) , Some ( _ ) ) = > {
eprintln ! ( "Error: ambigous configuration - cookie and cookie_file can't be specified at the same time" ) ;
std ::process ::exit ( 1 ) ;
}
}
}
impl Config {
impl Config {
/// Parses args, env vars, config files and post-processes them
/// Parses args, env vars, config files and post-processes them
pub fn from_args ( ) -> Config {
pub fn from_args ( ) -> Config {
@ -169,6 +184,9 @@ impl Config {
let ( mut config , _ ) =
let ( mut config , _ ) =
internal ::Config ::including_optional_config_files ( configs ) . unwrap_or_exit ( ) ;
internal ::Config ::including_optional_config_files ( configs ) . unwrap_or_exit ( ) ;
let cookie_getter =
create_cookie_getter ( config . cookie , config . cookie_file , & config . daemon_dir ) ;
let db_subdir = match config . network {
let db_subdir = match config . network {
// We must keep the name "mainnet" due to backwards compatibility
// We must keep the name "mainnet" due to backwards compatibility
Network ::Bitcoin = > "mainnet" ,
Network ::Bitcoin = > "mainnet" ,
@ -241,7 +259,6 @@ impl Config {
db_path : config . db_dir ,
db_path : config . db_dir ,
daemon_dir : config . daemon_dir ,
daemon_dir : config . daemon_dir ,
daemon_rpc_addr ,
daemon_rpc_addr ,
cookie : config . cookie ,
electrum_rpc_addr ,
electrum_rpc_addr ,
monitoring_addr ,
monitoring_addr ,
jsonrpc_import : config . jsonrpc_import ,
jsonrpc_import : config . jsonrpc_import ,
@ -251,28 +268,61 @@ impl Config {
blocktxids_cache_size : ( config . blocktxids_cache_size_mb * MB ) as usize ,
blocktxids_cache_size : ( config . blocktxids_cache_size_mb * MB ) as usize ,
txid_limit : config . txid_limit ,
txid_limit : config . txid_limit ,
server_banner : config . server_banner ,
server_banner : config . server_banner ,
cookie_getter ,
} ;
} ;
eprintln ! ( "{:?}" , config ) ;
eprintln ! ( "{:?}" , config ) ;
config
config
}
}
pub fn cookie_getter ( & self ) -> Arc < dyn CookieGetter > {
pub fn cookie_getter ( & self ) -> Arc < dyn CookieGetter > {
if let Some ( ref value ) = self . cookie {
Arc ::clone ( & self . cookie_getter )
Arc ::new ( StaticCookie {
}
value : value . as_bytes ( ) . to_vec ( ) ,
}
} )
} else {
// CookieGetter + Debug isn't implemented in Rust, so we have to skip cookie_getter
Arc ::new ( CookieFile {
macro_rules ! debug_struct {
daemon_dir : self . daemon_dir . clone ( ) ,
( $name :ty , $( $field :ident , ) * ) = > {
} )
impl fmt ::Debug for $name {
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
f . debug_struct ( stringify ! ( $name ) )
$(
. field ( stringify ! ( $field ) , & self . $field )
) *
. finish ( )
}
}
}
}
}
}
}
debug_struct ! { Config ,
log ,
network_type ,
db_path ,
daemon_dir ,
daemon_rpc_addr ,
electrum_rpc_addr ,
monitoring_addr ,
jsonrpc_import ,
index_batch_size ,
bulk_index_threads ,
tx_cache_size ,
txid_limit ,
server_banner ,
blocktxids_cache_size ,
}
struct StaticCookie {
struct StaticCookie {
value : Vec < u8 > ,
value : Vec < u8 > ,
}
}
impl StaticCookie {
fn from_string ( value : String ) -> Self {
StaticCookie {
value : value . into ( ) ,
}
}
}
impl CookieGetter for StaticCookie {
impl CookieGetter for StaticCookie {
fn get ( & self ) -> Result < Vec < u8 > > {
fn get ( & self ) -> Result < Vec < u8 > > {
Ok ( self . value . clone ( ) )
Ok ( self . value . clone ( ) )
@ -280,14 +330,28 @@ impl CookieGetter for StaticCookie {
}
}
struct CookieFile {
struct CookieFile {
daemon_dir : PathBuf ,
cookie_file : PathBuf ,
}
impl CookieFile {
fn from_daemon_dir ( daemon_dir : & Path ) -> Self {
CookieFile {
cookie_file : daemon_dir . join ( ".cookie" ) ,
}
}
fn from_file ( cookie_file : PathBuf ) -> Self {
CookieFile { cookie_file }
}
}
}
impl CookieGetter for CookieFile {
impl CookieGetter for CookieFile {
fn get ( & self ) -> Result < Vec < u8 > > {
fn get ( & self ) -> Result < Vec < u8 > > {
let path = self . daemon_dir . join ( ".cookie" ) ;
let contents = fs ::read ( & self . cookie_file ) . chain_err ( | | {
let contents = fs ::read ( & path ) . chain_err ( | | {
ErrorKind ::Connection ( format ! (
ErrorKind ::Connection ( format ! ( "failed to read cookie from {:?}" , path ) )
"failed to read cookie from {}" ,
self . cookie_file . display ( )
) )
} ) ? ;
} ) ? ;
Ok ( contents )
Ok ( contents )
}
}