complete quick'n'dirty light CLI
This commit is contained in:
parent
73b2dd7a59
commit
83911a7290
100
parity/dapps.rs
100
parity/dapps.rs
@ -18,13 +18,15 @@ use std::path::PathBuf;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use dir::default_data_path;
|
use dir::default_data_path;
|
||||||
use ethcore::client::Client;
|
use ethcore::client::{Client, BlockChainClient, BlockId};
|
||||||
|
use ethcore::transaction::{Transaction, Action};
|
||||||
use ethcore_rpc::informant::RpcStats;
|
use ethcore_rpc::informant::RpcStats;
|
||||||
use ethsync::SyncProvider;
|
|
||||||
use hash_fetch::fetch::Client as FetchClient;
|
use hash_fetch::fetch::Client as FetchClient;
|
||||||
|
use hash_fetch::urlhint::ContractClient;
|
||||||
use helpers::replace_home;
|
use helpers::replace_home;
|
||||||
use rpc_apis::{self, SignerService};
|
use rpc_apis::{self, SignerService};
|
||||||
use parity_reactor;
|
use parity_reactor;
|
||||||
|
use util::{Bytes, Address, U256};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
@ -58,17 +60,56 @@ impl Default for Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Dependencies {
|
/// Registrar implementation of the full client.
|
||||||
pub apis: Arc<rpc_apis::FullDependencies>,
|
pub struct FullRegistrar {
|
||||||
|
/// Handle to the full client.
|
||||||
pub client: Arc<Client>,
|
pub client: Arc<Client>,
|
||||||
pub sync: Arc<SyncProvider>,
|
}
|
||||||
|
|
||||||
|
impl ContractClient for FullRegistrar {
|
||||||
|
fn registrar(&self) -> Result<Address, String> {
|
||||||
|
self.client.additional_params().get("registrar")
|
||||||
|
.ok_or_else(|| "Registrar not defined.".into())
|
||||||
|
.and_then(|registrar| {
|
||||||
|
registrar.parse().map_err(|e| format!("Invalid registrar address: {:?}", e))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&self, address: Address, data: Bytes) -> Result<Bytes, String> {
|
||||||
|
let from = Address::default();
|
||||||
|
let transaction = Transaction {
|
||||||
|
nonce: self.client.latest_nonce(&from),
|
||||||
|
action: Action::Call(address),
|
||||||
|
gas: U256::from(50_000_000),
|
||||||
|
gas_price: U256::default(),
|
||||||
|
value: U256::default(),
|
||||||
|
data: data,
|
||||||
|
}.fake_sign(from);
|
||||||
|
|
||||||
|
self.client.call(&transaction, BlockId::Latest, Default::default())
|
||||||
|
.map_err(|e| format!("{:?}", e))
|
||||||
|
.map(|executed| {
|
||||||
|
executed.output
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: light client implementation forwarding to OnDemand and waiting for future
|
||||||
|
// to resolve.
|
||||||
|
|
||||||
|
pub struct Dependencies<D: rpc_apis::Dependencies> {
|
||||||
|
pub apis: Arc<D>,
|
||||||
|
pub sync_status: Arc<::ethcore_dapps::SyncStatus>,
|
||||||
|
pub contract_client: Arc<ContractClient>,
|
||||||
pub remote: parity_reactor::TokioRemote,
|
pub remote: parity_reactor::TokioRemote,
|
||||||
pub fetch: FetchClient,
|
pub fetch: FetchClient,
|
||||||
pub signer: Arc<SignerService>,
|
pub signer: Arc<SignerService>,
|
||||||
pub stats: Arc<RpcStats>,
|
pub stats: Arc<RpcStats>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<WebappServer>, String> {
|
pub fn new<D>(configuration: Configuration, deps: Dependencies<D>) -> Result<Option<WebappServer>, String>
|
||||||
|
where D: rpc_apis::Dependencies
|
||||||
|
{
|
||||||
if !configuration.enabled {
|
if !configuration.enabled {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
@ -130,21 +171,16 @@ mod server {
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::io;
|
use std::io;
|
||||||
use util::{Bytes, Address, U256};
|
|
||||||
|
|
||||||
use ansi_term::Colour;
|
use ansi_term::Colour;
|
||||||
use ethcore::transaction::{Transaction, Action};
|
|
||||||
use ethcore::client::{Client, BlockChainClient, BlockId};
|
|
||||||
use ethcore_dapps::{AccessControlAllowOrigin, Host};
|
use ethcore_dapps::{AccessControlAllowOrigin, Host};
|
||||||
use ethcore_rpc::is_major_importing;
|
|
||||||
use hash_fetch::urlhint::ContractClient;
|
|
||||||
use parity_reactor;
|
use parity_reactor;
|
||||||
use rpc_apis;
|
use rpc_apis;
|
||||||
|
|
||||||
pub use ethcore_dapps::Server as WebappServer;
|
pub use ethcore_dapps::Server as WebappServer;
|
||||||
|
|
||||||
pub fn setup_dapps_server(
|
pub fn setup_dapps_server<D: rpc_apis::Dependencies>(
|
||||||
deps: Dependencies,
|
deps: Dependencies<D>,
|
||||||
dapps_path: PathBuf,
|
dapps_path: PathBuf,
|
||||||
extra_dapps: Vec<PathBuf>,
|
extra_dapps: Vec<PathBuf>,
|
||||||
url: &SocketAddr,
|
url: &SocketAddr,
|
||||||
@ -157,18 +193,16 @@ mod server {
|
|||||||
|
|
||||||
let server = dapps::ServerBuilder::new(
|
let server = dapps::ServerBuilder::new(
|
||||||
&dapps_path,
|
&dapps_path,
|
||||||
Arc::new(Registrar { client: deps.client.clone() }),
|
deps.contract_client,
|
||||||
parity_reactor::Remote::new(deps.remote.clone()),
|
parity_reactor::Remote::new(deps.remote.clone()),
|
||||||
);
|
);
|
||||||
let allowed_hosts: Option<Vec<_>> = allowed_hosts.map(|hosts| hosts.into_iter().map(Host::from).collect());
|
let allowed_hosts: Option<Vec<_>> = allowed_hosts.map(|hosts| hosts.into_iter().map(Host::from).collect());
|
||||||
let cors: Option<Vec<_>> = cors.map(|cors| cors.into_iter().map(AccessControlAllowOrigin::from).collect());
|
let cors: Option<Vec<_>> = cors.map(|cors| cors.into_iter().map(AccessControlAllowOrigin::from).collect());
|
||||||
|
|
||||||
let sync = deps.sync.clone();
|
|
||||||
let client = deps.client.clone();
|
|
||||||
let signer = deps.signer.clone();
|
let signer = deps.signer.clone();
|
||||||
let server = server
|
let server = server
|
||||||
.fetch(deps.fetch.clone())
|
.fetch(deps.fetch.clone())
|
||||||
.sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info())))
|
.sync_status(deps.sync_status)
|
||||||
.web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token)))
|
.web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token)))
|
||||||
.extra_dapps(&extra_dapps)
|
.extra_dapps(&extra_dapps)
|
||||||
.signer_address(deps.signer.address())
|
.signer_address(deps.signer.address())
|
||||||
@ -201,36 +235,4 @@ mod server {
|
|||||||
Ok(server) => Ok(server),
|
Ok(server) => Ok(server),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Registrar {
|
|
||||||
client: Arc<Client>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ContractClient for Registrar {
|
|
||||||
fn registrar(&self) -> Result<Address, String> {
|
|
||||||
self.client.additional_params().get("registrar")
|
|
||||||
.ok_or_else(|| "Registrar not defined.".into())
|
|
||||||
.and_then(|registrar| {
|
|
||||||
registrar.parse().map_err(|e| format!("Invalid registrar address: {:?}", e))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&self, address: Address, data: Bytes) -> Result<Bytes, String> {
|
|
||||||
let from = Address::default();
|
|
||||||
let transaction = Transaction {
|
|
||||||
nonce: self.client.latest_nonce(&from),
|
|
||||||
action: Action::Call(address),
|
|
||||||
gas: U256::from(50_000_000),
|
|
||||||
gas_price: U256::default(),
|
|
||||||
value: U256::default(),
|
|
||||||
data: data,
|
|
||||||
}.fake_sign(from);
|
|
||||||
|
|
||||||
self.client.call(&transaction, BlockId::Latest, Default::default())
|
|
||||||
.map_err(|e| format!("{:?}", e))
|
|
||||||
.map(|executed| {
|
|
||||||
executed.output
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,6 @@ pub struct LightDependencies {
|
|||||||
pub on_demand: Arc<::light::on_demand::OnDemand>,
|
pub on_demand: Arc<::light::on_demand::OnDemand>,
|
||||||
pub cache: Arc<Mutex<LightDataCache>>,
|
pub cache: Arc<Mutex<LightDataCache>>,
|
||||||
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
|
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
|
||||||
pub updater: Arc<Updater>,
|
|
||||||
pub dapps_interface: Option<String>,
|
pub dapps_interface: Option<String>,
|
||||||
pub dapps_port: Option<u16>,
|
pub dapps_port: Option<u16>,
|
||||||
pub fetch: FetchClient,
|
pub fetch: FetchClient,
|
||||||
|
@ -30,6 +30,7 @@ use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
|
|||||||
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
|
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
|
||||||
use ethcore::snapshot;
|
use ethcore::snapshot;
|
||||||
use ethcore::verification::queue::VerifierSettings;
|
use ethcore::verification::queue::VerifierSettings;
|
||||||
|
use light::Cache as LightDataCache;
|
||||||
use ethsync::SyncConfig;
|
use ethsync::SyncConfig;
|
||||||
use informant::Informant;
|
use informant::Informant;
|
||||||
use updater::{UpdatePolicy, Updater};
|
use updater::{UpdatePolicy, Updater};
|
||||||
@ -61,6 +62,10 @@ const SNAPSHOT_PERIOD: u64 = 10000;
|
|||||||
// how many blocks to wait before starting a periodic snapshot.
|
// how many blocks to wait before starting a periodic snapshot.
|
||||||
const SNAPSHOT_HISTORY: u64 = 100;
|
const SNAPSHOT_HISTORY: u64 = 100;
|
||||||
|
|
||||||
|
// Number of minutes before a given gas price corpus should expire.
|
||||||
|
// Light client only.
|
||||||
|
const GAS_CORPUS_EXPIRATION_MINUTES: i64 = 60 * 6;
|
||||||
|
|
||||||
// Pops along with error messages when a password is missing or invalid.
|
// Pops along with error messages when a password is missing or invalid.
|
||||||
const VERIFY_PASSWORD_HINT: &'static str = "Make sure valid password is present in files passed using `--password` or in the configuration file.";
|
const VERIFY_PASSWORD_HINT: &'static str = "Make sure valid password is present in files passed using `--password` or in the configuration file.";
|
||||||
|
|
||||||
@ -155,7 +160,7 @@ impl ::local_store::NodeInfo for FullNodeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// helper for light execution.
|
// helper for light execution.
|
||||||
fn execute_light(cmd: RunCmd, can_restart: bool, _logger: Arc<RotatingLogger>) -> Result<(bool, Option<String>), String> {
|
fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> Result<(bool, Option<String>), String> {
|
||||||
use light::client as light_client;
|
use light::client as light_client;
|
||||||
use ethsync::{LightSyncParams, LightSync, ManageNetwork};
|
use ethsync::{LightSyncParams, LightSync, ManageNetwork};
|
||||||
use util::RwLock;
|
use util::RwLock;
|
||||||
@ -206,7 +211,7 @@ fn execute_light(cmd: RunCmd, can_restart: bool, _logger: Arc<RotatingLogger>) -
|
|||||||
let service = light_client::Service::start(config, &spec, &db_dirs.client_path(algorithm))
|
let service = light_client::Service::start(config, &spec, &db_dirs.client_path(algorithm))
|
||||||
.map_err(|e| format!("Error starting light client: {}", e))?;
|
.map_err(|e| format!("Error starting light client: {}", e))?;
|
||||||
let txq = Arc::new(RwLock::new(::light::transaction_queue::TransactionQueue::default()));
|
let txq = Arc::new(RwLock::new(::light::transaction_queue::TransactionQueue::default()));
|
||||||
let provider = ::light::provider::LightProvider::new(service.client().clone(), txq);
|
let provider = ::light::provider::LightProvider::new(service.client().clone(), txq.clone());
|
||||||
|
|
||||||
// start network.
|
// start network.
|
||||||
// set up bootnodes
|
// set up bootnodes
|
||||||
@ -215,6 +220,13 @@ fn execute_light(cmd: RunCmd, can_restart: bool, _logger: Arc<RotatingLogger>) -
|
|||||||
net_conf.boot_nodes = spec.nodes.clone();
|
net_conf.boot_nodes = spec.nodes.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: configurable cache size.
|
||||||
|
let cache = LightDataCache::new(Default::default(), ::time::Duration::minutes(GAS_CORPUS_EXPIRATION_MINUTES));
|
||||||
|
let cache = Arc::new(::util::Mutex::new(cache));
|
||||||
|
|
||||||
|
// start on_demand service.
|
||||||
|
let on_demand = Arc::new(::light::on_demand::OnDemand::new(cache.clone()));
|
||||||
|
|
||||||
// set network path.
|
// set network path.
|
||||||
net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned());
|
net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned());
|
||||||
let sync_params = LightSyncParams {
|
let sync_params = LightSyncParams {
|
||||||
@ -222,16 +234,70 @@ fn execute_light(cmd: RunCmd, can_restart: bool, _logger: Arc<RotatingLogger>) -
|
|||||||
client: Arc::new(provider),
|
client: Arc::new(provider),
|
||||||
network_id: cmd.network_id.unwrap_or(spec.network_id()),
|
network_id: cmd.network_id.unwrap_or(spec.network_id()),
|
||||||
subprotocol_name: ::ethsync::LIGHT_PROTOCOL,
|
subprotocol_name: ::ethsync::LIGHT_PROTOCOL,
|
||||||
|
handlers: vec![on_demand.clone()],
|
||||||
};
|
};
|
||||||
let light_sync = LightSync::new(sync_params).map_err(|e| format!("Error starting network: {}", e))?;
|
let light_sync = LightSync::new(sync_params).map_err(|e| format!("Error starting network: {}", e))?;
|
||||||
|
let light_sync = Arc::new(light_sync);
|
||||||
light_sync.start_network();
|
light_sync.start_network();
|
||||||
|
|
||||||
// start RPCs.
|
// start RPCs.
|
||||||
|
// spin up event loop
|
||||||
|
let event_loop = EventLoop::spawn();
|
||||||
|
|
||||||
|
// fetch service
|
||||||
|
let fetch = FetchClient::new().map_err(|e| format!("Error starting fetch client: {:?}", e))?;
|
||||||
let passwords = passwords_from_files(&cmd.acc_conf.password_files)?;
|
let passwords = passwords_from_files(&cmd.acc_conf.password_files)?;
|
||||||
|
|
||||||
// prepare account provider
|
// prepare account provider
|
||||||
let _account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?);
|
let account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?);
|
||||||
// rest TODO
|
let rpc_stats = Arc::new(informant::RpcStats::default());
|
||||||
|
let signer_path = cmd.signer_conf.signer_path.clone();
|
||||||
|
|
||||||
|
let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
|
||||||
|
signer_service: Arc::new(rpc_apis::SignerService::new(move || {
|
||||||
|
signer::generate_new_token(signer_path.clone()).map_err(|e| format!("{:?}", e))
|
||||||
|
}, cmd.ui_address)),
|
||||||
|
client: service.client().clone(),
|
||||||
|
sync: light_sync.clone(),
|
||||||
|
net: light_sync.clone(),
|
||||||
|
secret_store: account_provider,
|
||||||
|
logger: logger,
|
||||||
|
settings: Arc::new(cmd.net_settings),
|
||||||
|
on_demand: on_demand,
|
||||||
|
cache: cache,
|
||||||
|
transaction_queue: txq,
|
||||||
|
dapps_interface: match cmd.dapps_conf.enabled {
|
||||||
|
true => Some(cmd.dapps_conf.interface.clone()),
|
||||||
|
false => None,
|
||||||
|
},
|
||||||
|
dapps_port: match cmd.dapps_conf.enabled {
|
||||||
|
true => Some(cmd.dapps_conf.port),
|
||||||
|
false => None,
|
||||||
|
},
|
||||||
|
fetch: fetch,
|
||||||
|
geth_compatibility: cmd.geth_compatibility,
|
||||||
|
});
|
||||||
|
|
||||||
|
let dependencies = rpc::Dependencies {
|
||||||
|
apis: deps_for_rpc_apis.clone(),
|
||||||
|
remote: event_loop.raw_remote(),
|
||||||
|
stats: rpc_stats.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// start rpc servers
|
||||||
|
let _http_server = rpc::new_http(cmd.http_conf, &dependencies)?;
|
||||||
|
let _ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?;
|
||||||
|
|
||||||
|
// the signer server
|
||||||
|
let signer_deps = signer::Dependencies {
|
||||||
|
apis: deps_for_rpc_apis.clone(),
|
||||||
|
remote: event_loop.raw_remote(),
|
||||||
|
rpc_stats: rpc_stats.clone(),
|
||||||
|
};
|
||||||
|
let signing_queue = deps_for_rpc_apis.signer_service.queue();
|
||||||
|
let _signer_server = signer::start(cmd.signer_conf.clone(), signing_queue, signer_deps)?;
|
||||||
|
|
||||||
|
// TODO: Dapps
|
||||||
|
|
||||||
// wait for ctrl-c.
|
// wait for ctrl-c.
|
||||||
Ok(wait_for_exit(panic_handler, None, None, can_restart))
|
Ok(wait_for_exit(panic_handler, None, None, can_restart))
|
||||||
@ -536,14 +602,19 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
|||||||
let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?;
|
let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?;
|
||||||
|
|
||||||
// the dapps server
|
// the dapps server
|
||||||
let dapps_deps = dapps::Dependencies {
|
let dapps_deps = {
|
||||||
|
let (sync, client) = (sync_provider.clone(), client.clone());
|
||||||
|
let contract_client = Arc::new(::dapps::FullRegistrar { client: client.clone() });
|
||||||
|
|
||||||
|
dapps::Dependencies {
|
||||||
apis: deps_for_rpc_apis.clone(),
|
apis: deps_for_rpc_apis.clone(),
|
||||||
client: client.clone(),
|
sync_status: Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info())),
|
||||||
sync: sync_provider.clone(),
|
contract_client: contract_client,
|
||||||
remote: event_loop.raw_remote(),
|
remote: event_loop.raw_remote(),
|
||||||
fetch: fetch.clone(),
|
fetch: fetch.clone(),
|
||||||
signer: deps_for_rpc_apis.signer_service.clone(),
|
signer: deps_for_rpc_apis.signer_service.clone(),
|
||||||
stats: rpc_stats.clone(),
|
stats: rpc_stats.clone(),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let dapps_server = dapps::new(cmd.dapps_conf.clone(), dapps_deps)?;
|
let dapps_server = dapps::new(cmd.dapps_conf.clone(), dapps_deps)?;
|
||||||
|
|
||||||
|
@ -662,6 +662,8 @@ pub struct LightSyncParams<L> {
|
|||||||
pub network_id: u64,
|
pub network_id: u64,
|
||||||
/// Subprotocol name.
|
/// Subprotocol name.
|
||||||
pub subprotocol_name: [u8; 3],
|
pub subprotocol_name: [u8; 3],
|
||||||
|
/// Other handlers to attach.
|
||||||
|
pub handlers: Vec<Arc<LightHandler>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Service for light synchronization.
|
/// Service for light synchronization.
|
||||||
@ -696,6 +698,10 @@ impl LightSync {
|
|||||||
let sync_handler = try!(SyncHandler::new(params.client.clone()));
|
let sync_handler = try!(SyncHandler::new(params.client.clone()));
|
||||||
light_proto.add_handler(Arc::new(sync_handler));
|
light_proto.add_handler(Arc::new(sync_handler));
|
||||||
|
|
||||||
|
for handler in params.handlers {
|
||||||
|
light_proto.add_handler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
Arc::new(light_proto)
|
Arc::new(light_proto)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user