Implement parity_versionInfo & parity_setChain on LC; fix parity_setChain (#10312)
* Light client: implement parity_versionInfo RPC * Light client: implement set_exit_handler & parity_setChain RPC * parity_setChain RPC: return an error if failed (instead of `true`) * Implement eth_subscribe('syncing') RPC for full node & light node * Fix indentation * Revert commit: Implement eth_subscribe('syncing') * Revert change to Cr callback function
This commit is contained in:
parent
1bd4564216
commit
7014642815
@ -116,6 +116,9 @@ pub trait LightChainClient: Send + Sync {
|
|||||||
/// Query whether a block is known.
|
/// Query whether a block is known.
|
||||||
fn is_known(&self, hash: &H256) -> bool;
|
fn is_known(&self, hash: &H256) -> bool;
|
||||||
|
|
||||||
|
/// Set the chain via a spec name.
|
||||||
|
fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()>;
|
||||||
|
|
||||||
/// Clear the queue.
|
/// Clear the queue.
|
||||||
fn clear_queue(&self);
|
fn clear_queue(&self);
|
||||||
|
|
||||||
@ -164,6 +167,8 @@ pub struct Client<T> {
|
|||||||
listeners: RwLock<Vec<Weak<LightChainNotify>>>,
|
listeners: RwLock<Vec<Weak<LightChainNotify>>>,
|
||||||
fetcher: T,
|
fetcher: T,
|
||||||
verify_full: bool,
|
verify_full: bool,
|
||||||
|
/// A closure to call when we want to restart the client
|
||||||
|
exit_handler: Mutex<Option<Box<Fn(String) + 'static + Send>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ChainDataFetcher> Client<T> {
|
impl<T: ChainDataFetcher> Client<T> {
|
||||||
@ -190,6 +195,7 @@ impl<T: ChainDataFetcher> Client<T> {
|
|||||||
listeners: RwLock::new(vec![]),
|
listeners: RwLock::new(vec![]),
|
||||||
fetcher,
|
fetcher,
|
||||||
verify_full: config.verify_full,
|
verify_full: config.verify_full,
|
||||||
|
exit_handler: Mutex::new(None),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,6 +366,14 @@ impl<T: ChainDataFetcher> Client<T> {
|
|||||||
self.chain.heap_size_of_children()
|
self.chain.heap_size_of_children()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set a closure to call when the client wants to be restarted.
|
||||||
|
///
|
||||||
|
/// The parameter passed to the callback is the name of the new chain spec to use after
|
||||||
|
/// the restart.
|
||||||
|
pub fn set_exit_handler<F>(&self, f: F) where F: Fn(String) + 'static + Send {
|
||||||
|
*self.exit_handler.lock() = Some(Box::new(f));
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a handle to the verification engine.
|
/// Get a handle to the verification engine.
|
||||||
pub fn engine(&self) -> &Arc<EthEngine> {
|
pub fn engine(&self) -> &Arc<EthEngine> {
|
||||||
&self.engine
|
&self.engine
|
||||||
@ -563,6 +577,17 @@ impl<T: ChainDataFetcher> LightChainClient for Client<T> {
|
|||||||
Client::engine(self)
|
Client::engine(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()> {
|
||||||
|
trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name);
|
||||||
|
if let Some(ref h) = *self.exit_handler.lock() {
|
||||||
|
(*h)(new_spec_name);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
warn!("Not hypervised; cannot change chain.");
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_known(&self, hash: &H256) -> bool {
|
fn is_known(&self, hash: &H256) -> bool {
|
||||||
self.status(hash) == BlockStatus::InChain
|
self.status(hash) == BlockStatus::InChain
|
||||||
}
|
}
|
||||||
|
@ -1706,15 +1706,17 @@ impl BlockChainClient for Client {
|
|||||||
self.config.spec_name.clone()
|
self.config.spec_name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_spec_name(&self, new_spec_name: String) {
|
fn set_spec_name(&self, new_spec_name: String) -> Result<(), ()> {
|
||||||
trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name);
|
trace!(target: "mode", "Client::set_spec_name({:?})", new_spec_name);
|
||||||
if !self.enabled.load(AtomicOrdering::Relaxed) {
|
if !self.enabled.load(AtomicOrdering::Relaxed) {
|
||||||
return;
|
return Err(());
|
||||||
}
|
}
|
||||||
if let Some(ref h) = *self.exit_handler.lock() {
|
if let Some(ref h) = *self.exit_handler.lock() {
|
||||||
(*h)(new_spec_name);
|
(*h)(new_spec_name);
|
||||||
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
warn!("Not hypervised; cannot change chain.");
|
warn!("Not hypervised; cannot change chain.");
|
||||||
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,7 +863,7 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
|
|
||||||
fn spec_name(&self) -> String { "foundation".into() }
|
fn spec_name(&self) -> String { "foundation".into() }
|
||||||
|
|
||||||
fn set_spec_name(&self, _: String) { unimplemented!(); }
|
fn set_spec_name(&self, _: String) -> Result<(), ()> { unimplemented!(); }
|
||||||
|
|
||||||
fn disable(&self) { self.disabled.store(true, AtomicOrder::Relaxed); }
|
fn disable(&self) { self.disabled.store(true, AtomicOrder::Relaxed); }
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra
|
|||||||
fn spec_name(&self) -> String;
|
fn spec_name(&self) -> String;
|
||||||
|
|
||||||
/// Set the chain via a spec name.
|
/// Set the chain via a spec name.
|
||||||
fn set_spec_name(&self, spec_name: String);
|
fn set_spec_name(&self, spec_name: String) -> Result<(), ()>;
|
||||||
|
|
||||||
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
||||||
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
||||||
|
@ -634,7 +634,7 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
|
|||||||
handler.extend_with(ParityAccounts::to_delegate(ParityAccountsClient::new(&self.accounts)));
|
handler.extend_with(ParityAccounts::to_delegate(ParityAccountsClient::new(&self.accounts)));
|
||||||
}
|
}
|
||||||
Api::ParitySet => handler.extend_with(
|
Api::ParitySet => handler.extend_with(
|
||||||
light::ParitySetClient::new(self.sync.clone(), self.fetch.clone())
|
light::ParitySetClient::new(self.client.clone(), self.sync.clone(), self.fetch.clone())
|
||||||
.to_delegate(),
|
.to_delegate(),
|
||||||
),
|
),
|
||||||
Api::Traces => handler.extend_with(light::TracesClient.to_delegate()),
|
Api::Traces => handler.extend_with(light::TracesClient.to_delegate()),
|
||||||
|
@ -165,7 +165,9 @@ impl ::local_store::NodeInfo for FullNodeInfo {
|
|||||||
type LightClient = ::light::client::Client<::light_helpers::EpochFetch>;
|
type LightClient = ::light::client::Client<::light_helpers::EpochFetch>;
|
||||||
|
|
||||||
// helper for light execution.
|
// helper for light execution.
|
||||||
fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<RunningClient, String> {
|
fn execute_light_impl<Cr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq: Cr) -> Result<RunningClient, String>
|
||||||
|
where Cr: Fn(String) + 'static + Send
|
||||||
|
{
|
||||||
use light::client as light_client;
|
use light::client as light_client;
|
||||||
use sync::{LightSyncParams, LightSync, ManageNetwork};
|
use sync::{LightSyncParams, LightSync, ManageNetwork};
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
@ -367,6 +369,8 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
|
|||||||
service.add_notify(informant.clone());
|
service.add_notify(informant.clone());
|
||||||
service.register_handler(informant.clone()).map_err(|_| "Unable to register informant handler".to_owned())?;
|
service.register_handler(informant.clone()).map_err(|_| "Unable to register informant handler".to_owned())?;
|
||||||
|
|
||||||
|
client.set_exit_handler(on_client_rq);
|
||||||
|
|
||||||
Ok(RunningClient {
|
Ok(RunningClient {
|
||||||
inner: RunningClientInner::Light {
|
inner: RunningClientInner::Light {
|
||||||
rpc: rpc_direct,
|
rpc: rpc_direct,
|
||||||
@ -930,7 +934,7 @@ pub fn execute<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>,
|
|||||||
Rr: Fn() + 'static + Send
|
Rr: Fn() + 'static + Send
|
||||||
{
|
{
|
||||||
if cmd.light {
|
if cmd.light {
|
||||||
execute_light_impl(cmd, logger)
|
execute_light_impl(cmd, logger, on_client_rq)
|
||||||
} else {
|
} else {
|
||||||
execute_impl(cmd, logger, on_client_rq, on_updater_rq)
|
execute_impl(cmd, logger, on_client_rq, on_updater_rq)
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ mod codes {
|
|||||||
pub const NO_PEERS: i64 = -32066;
|
pub const NO_PEERS: i64 = -32066;
|
||||||
pub const DEPRECATED: i64 = -32070;
|
pub const DEPRECATED: i64 = -32070;
|
||||||
pub const EXPERIMENTAL_RPC: i64 = -32071;
|
pub const EXPERIMENTAL_RPC: i64 = -32071;
|
||||||
|
pub const CANNOT_RESTART: i64 = -32080;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unimplemented(details: Option<String>) -> Error {
|
pub fn unimplemented(details: Option<String>) -> Error {
|
||||||
@ -125,6 +126,14 @@ pub fn account<T: fmt::Debug>(error: &str, details: T) -> Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cannot_restart() -> Error {
|
||||||
|
Error {
|
||||||
|
code: ErrorCode::ServerError(codes::CANNOT_RESTART),
|
||||||
|
message: "Parity could not be restarted. This feature is disabled in development mode and if the binary name isn't parity.".into(),
|
||||||
|
data: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Internal error signifying a logic error in code.
|
/// Internal error signifying a logic error in code.
|
||||||
/// Should not be used when function can just fail
|
/// Should not be used when function can just fail
|
||||||
/// because of invalid parameters or incomplete node state.
|
/// because of invalid parameters or incomplete node state.
|
||||||
|
@ -24,6 +24,7 @@ use crypto::DEFAULT_MAC;
|
|||||||
use ethkey::{crypto::ecies, Brain, Generator};
|
use ethkey::{crypto::ecies, Brain, Generator};
|
||||||
use ethstore::random_phrase;
|
use ethstore::random_phrase;
|
||||||
use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork};
|
use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork};
|
||||||
|
use updater::VersionInfo as UpdaterVersionInfo;
|
||||||
use ethereum_types::{H64, H160, H256, H512, U64, U256};
|
use ethereum_types::{H64, H160, H256, H512, U64, U256};
|
||||||
use ethcore_logger::RotatingLogger;
|
use ethcore_logger::RotatingLogger;
|
||||||
|
|
||||||
@ -299,7 +300,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn version_info(&self) -> Result<VersionInfo> {
|
fn version_info(&self) -> Result<VersionInfo> {
|
||||||
Err(errors::light_unimplemented(None))
|
Ok(UpdaterVersionInfo::this().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn releases_info(&self) -> Result<Option<OperationsInfo>> {
|
fn releases_info(&self) -> Result<Option<OperationsInfo>> {
|
||||||
|
@ -23,6 +23,7 @@ use std::sync::Arc;
|
|||||||
use ethereum_types::{H160, H256, U256};
|
use ethereum_types::{H160, H256, U256};
|
||||||
use fetch::{self, Fetch};
|
use fetch::{self, Fetch};
|
||||||
use hash::keccak_buffer;
|
use hash::keccak_buffer;
|
||||||
|
use light::client::LightChainClient;
|
||||||
use sync::ManageNetwork;
|
use sync::ManageNetwork;
|
||||||
|
|
||||||
use jsonrpc_core::{Result, BoxFuture};
|
use jsonrpc_core::{Result, BoxFuture};
|
||||||
@ -33,14 +34,16 @@ use v1::types::{Bytes, ReleaseInfo, Transaction};
|
|||||||
|
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
pub struct ParitySetClient<F> {
|
pub struct ParitySetClient<F> {
|
||||||
|
client: Arc<LightChainClient>,
|
||||||
net: Arc<ManageNetwork>,
|
net: Arc<ManageNetwork>,
|
||||||
fetch: F,
|
fetch: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetch> ParitySetClient<F> {
|
impl<F: Fetch> ParitySetClient<F> {
|
||||||
/// Creates new `ParitySetClient` with given `Fetch`.
|
/// Creates new `ParitySetClient` with given `Fetch`.
|
||||||
pub fn new(net: Arc<ManageNetwork>, fetch: F) -> Self {
|
pub fn new(client: Arc<LightChainClient>, net: Arc<ManageNetwork>, fetch: F) -> Self {
|
||||||
ParitySetClient {
|
ParitySetClient {
|
||||||
|
client: client,
|
||||||
net: net,
|
net: net,
|
||||||
fetch: fetch,
|
fetch: fetch,
|
||||||
}
|
}
|
||||||
@ -118,8 +121,8 @@ impl<F: Fetch> ParitySet for ParitySetClient<F> {
|
|||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_spec_name(&self, _spec_name: String) -> Result<bool> {
|
fn set_spec_name(&self, spec_name: String) -> Result<bool> {
|
||||||
Err(errors::light_unimplemented(None))
|
self.client.set_spec_name(spec_name).map(|_| true).map_err(|()| errors::cannot_restart())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_content(&self, url: String) -> BoxFuture<H256> {
|
fn hash_content(&self, url: String) -> BoxFuture<H256> {
|
||||||
|
@ -211,8 +211,7 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_spec_name(&self, spec_name: String) -> Result<bool> {
|
fn set_spec_name(&self, spec_name: String) -> Result<bool> {
|
||||||
self.client.set_spec_name(spec_name);
|
self.client.set_spec_name(spec_name).map(|_| true).map_err(|()| errors::cannot_restart())
|
||||||
Ok(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_content(&self, url: String) -> BoxFuture<H256> {
|
fn hash_content(&self, url: String) -> BoxFuture<H256> {
|
||||||
|
Loading…
Reference in New Issue
Block a user