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 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 ethsync::SyncProvider;
|
||||
use hash_fetch::fetch::Client as FetchClient;
|
||||
use hash_fetch::urlhint::ContractClient;
|
||||
use helpers::replace_home;
|
||||
use rpc_apis::{self, SignerService};
|
||||
use parity_reactor;
|
||||
use util::{Bytes, Address, U256};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Configuration {
|
||||
@ -58,17 +60,56 @@ impl Default for Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Dependencies {
|
||||
pub apis: Arc<rpc_apis::FullDependencies>,
|
||||
/// Registrar implementation of the full client.
|
||||
pub struct FullRegistrar {
|
||||
/// Handle to the full 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 fetch: FetchClient,
|
||||
pub signer: Arc<SignerService>,
|
||||
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 {
|
||||
return Ok(None);
|
||||
}
|
||||
@ -130,21 +171,16 @@ mod server {
|
||||
use std::sync::Arc;
|
||||
use std::net::SocketAddr;
|
||||
use std::io;
|
||||
use util::{Bytes, Address, U256};
|
||||
|
||||
use ansi_term::Colour;
|
||||
use ethcore::transaction::{Transaction, Action};
|
||||
use ethcore::client::{Client, BlockChainClient, BlockId};
|
||||
use ethcore_dapps::{AccessControlAllowOrigin, Host};
|
||||
use ethcore_rpc::is_major_importing;
|
||||
use hash_fetch::urlhint::ContractClient;
|
||||
use parity_reactor;
|
||||
use rpc_apis;
|
||||
|
||||
pub use ethcore_dapps::Server as WebappServer;
|
||||
|
||||
pub fn setup_dapps_server(
|
||||
deps: Dependencies,
|
||||
pub fn setup_dapps_server<D: rpc_apis::Dependencies>(
|
||||
deps: Dependencies<D>,
|
||||
dapps_path: PathBuf,
|
||||
extra_dapps: Vec<PathBuf>,
|
||||
url: &SocketAddr,
|
||||
@ -157,18 +193,16 @@ mod server {
|
||||
|
||||
let server = dapps::ServerBuilder::new(
|
||||
&dapps_path,
|
||||
Arc::new(Registrar { client: deps.client.clone() }),
|
||||
deps.contract_client,
|
||||
parity_reactor::Remote::new(deps.remote.clone()),
|
||||
);
|
||||
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 sync = deps.sync.clone();
|
||||
let client = deps.client.clone();
|
||||
let signer = deps.signer.clone();
|
||||
let server = server
|
||||
.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)))
|
||||
.extra_dapps(&extra_dapps)
|
||||
.signer_address(deps.signer.address())
|
||||
@ -201,36 +235,4 @@ mod 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 cache: Arc<Mutex<LightDataCache>>,
|
||||
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
|
||||
pub updater: Arc<Updater>,
|
||||
pub dapps_interface: Option<String>,
|
||||
pub dapps_port: Option<u16>,
|
||||
pub fetch: FetchClient,
|
||||
|
@ -30,6 +30,7 @@ use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
|
||||
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
|
||||
use ethcore::snapshot;
|
||||
use ethcore::verification::queue::VerifierSettings;
|
||||
use light::Cache as LightDataCache;
|
||||
use ethsync::SyncConfig;
|
||||
use informant::Informant;
|
||||
use updater::{UpdatePolicy, Updater};
|
||||
@ -61,6 +62,10 @@ const SNAPSHOT_PERIOD: u64 = 10000;
|
||||
// how many blocks to wait before starting a periodic snapshot.
|
||||
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.
|
||||
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.
|
||||
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 ethsync::{LightSyncParams, LightSync, ManageNetwork};
|
||||
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))
|
||||
.map_err(|e| format!("Error starting light client: {}", e))?;
|
||||
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.
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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.
|
||||
net_conf.net_config_path = Some(db_dirs.network_path().to_string_lossy().into_owned());
|
||||
let sync_params = LightSyncParams {
|
||||
@ -222,16 +234,70 @@ fn execute_light(cmd: RunCmd, can_restart: bool, _logger: Arc<RotatingLogger>) -
|
||||
client: Arc::new(provider),
|
||||
network_id: cmd.network_id.unwrap_or(spec.network_id()),
|
||||
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 = Arc::new(light_sync);
|
||||
light_sync.start_network();
|
||||
|
||||
// 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)?;
|
||||
|
||||
// prepare account provider
|
||||
let _account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?);
|
||||
// rest TODO
|
||||
let account_provider = Arc::new(prepare_account_provider(&cmd.spec, &cmd.dirs, &spec.data_dir, cmd.acc_conf, &passwords)?);
|
||||
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.
|
||||
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)?;
|
||||
|
||||
// the dapps server
|
||||
let dapps_deps = dapps::Dependencies {
|
||||
apis: deps_for_rpc_apis.clone(),
|
||||
client: client.clone(),
|
||||
sync: sync_provider.clone(),
|
||||
remote: event_loop.raw_remote(),
|
||||
fetch: fetch.clone(),
|
||||
signer: deps_for_rpc_apis.signer_service.clone(),
|
||||
stats: rpc_stats.clone(),
|
||||
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(),
|
||||
sync_status: Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info())),
|
||||
contract_client: contract_client,
|
||||
remote: event_loop.raw_remote(),
|
||||
fetch: fetch.clone(),
|
||||
signer: deps_for_rpc_apis.signer_service.clone(),
|
||||
stats: rpc_stats.clone(),
|
||||
}
|
||||
};
|
||||
let dapps_server = dapps::new(cmd.dapps_conf.clone(), dapps_deps)?;
|
||||
|
||||
|
@ -662,6 +662,8 @@ pub struct LightSyncParams<L> {
|
||||
pub network_id: u64,
|
||||
/// Subprotocol name.
|
||||
pub subprotocol_name: [u8; 3],
|
||||
/// Other handlers to attach.
|
||||
pub handlers: Vec<Arc<LightHandler>>,
|
||||
}
|
||||
|
||||
/// Service for light synchronization.
|
||||
@ -696,6 +698,10 @@ impl LightSync {
|
||||
let sync_handler = try!(SyncHandler::new(params.client.clone()));
|
||||
light_proto.add_handler(Arc::new(sync_handler));
|
||||
|
||||
for handler in params.handlers {
|
||||
light_proto.add_handler(handler);
|
||||
}
|
||||
|
||||
Arc::new(light_proto)
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user